-
Notifications
You must be signed in to change notification settings - Fork 68
Implement Conversions
rule package
#919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lcartey
wants to merge
90
commits into
main
Choose a base branch
from
lcartey/cpp-conversions
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 57 commits
Commits
Show all changes
90 commits
Select commit
Hold shift + click to select a range
1d2aa2e
RULE-7-0-1 - NoConversionFromBool
lcartey 5b810c3
Rule 7.0.1: Address review issues
lcartey 62d5dcc
RULE-7-0-2 - NoImplicitBoolConversion
lcartey f92a2c9
Rule 7.0.2: Extend test case, support member function pointers
lcartey b62394a
Add Conversions exclusions file
lcartey a2c9912
RULE-7-0-6 - NumericAssignmentTypeMismatch
lcartey 229705f
Rule 7.0.6: Update test with better variable names
lcartey f870023
Rule 7.0.6: Fix id-expression detection
lcartey 0ed1689
Rule 7.0.6: Support reference types
lcartey 778b344
Rule 7.0.6: Ignore compound expressions
lcartey acfb253
Rule 7.0.6: Additional function return test cases
lcartey 9dbc39f
Rule 7.0.6: Clarify pass-by-value on parameters
lcartey b310e14
Rule 7.0.6: Add user defined operator tests
lcartey af2ff95
MISRA C++ 2023: Create StandardConversions library
lcartey ea7d168
MISRA C++ StandardConversions - improve detection of bitfield types
lcartey 5843258
Rule 7.0.6: Improve bitfield support
lcartey 01b517d
StandardConversions: Improve detection of numeric type category
lcartey 06eddfa
Rule 7.0.6: Add a test case for non-numeric (not covered)
lcartey a65c4cc
StandardConversions: Handle aggregate initialization
lcartey 04613cd
Add a library for determining constant expressions
lcartey 4be1395
Rule 7.0.6: Use BigInt for constant expressions
lcartey e87892e
Rule 7.0.6: add tests for cv-qualified types
lcartey 916fb3d
Rule 7.0.6: Support pointer to member cases
lcartey 2ec2814
Rule 7.0.6: Support functions with default parameters
lcartey e659944
Rule 7.0.6: Ignore deleted overloads
lcartey c0fe44d
Rule 7.0.6: Refactor overload independent code
lcartey 06ffbfb
Rule 7.0.6: Move aggregate tests to new file
lcartey fc63db1
Rule 7.0.6: Move operator tests to separate file
lcartey f68658a
Rule 7.0.6: Support constructor field initializers
lcartey 3fdaa98
Rule 7.0.6: Handle explicit conversions
lcartey 063a5cc
Rule 7.0.6: Improve tests for templates
lcartey 96d5c1b
MISRA C++ 2023: Rename StandardConversions library
lcartey 7c5fb87
Rule 7.0.6: Address performance issues
lcartey 6ddab35
Create Call library
lcartey 983f256
Extend ios stubs for C++
lcartey bb9f5a1
RULE-7-11-3 - FunctionPointerConversionContext
lcartey 2e75310
C++: Improve char_traits stubs
lcartey 4bf8d51
Improve C++ stubs for locales
lcartey 4d5e35f
Extend C++ stubs for locale
lcartey f2b5410
C++: Add optional stubs
lcartey 74946cf
Rule 7.0.3: NoCharacterNumericalValue.ql
lcartey a2d7ee3
RULE-7-0-5 - NoSignednessChangeFromPromotion
lcartey c25057d
Add sizeOfInt() predicate
lcartey 3a8dab1
Rule 7.0.5: Refactor to enable non-Conversions
lcartey 3cf9eac
Improve detection of integer promotions and usual arithmetic conversions
lcartey f50baa9
Format test case
lcartey a7ce6f5
Rule 7.0.5: Expand test cases
lcartey 9aed463
Ruley 7.0.5: Support lvalue conversions on assign operations
lcartey aac2dc2
Refactor to use NumericType
lcartey 92c7dac
Rule 7.0.5: Add pointer tests (should be ignored)
lcartey 4be88a3
Rule 7.0.5: Add failing test case
lcartey f1502d6
Rule 7.0.5: Add test cases for enum conversions
lcartey 89485d5
Conversions: Swap some queries around
lcartey 6845cdc
RULE-7-0-4 - InappropriateBitwiseOrShiftOperands
lcartey db58704
Test large and negative constants, use BigInt
lcartey 3d2616a
Rule 7.0.4: Add support for shift-assignment operators
lcartey 05cfc2b
Rule 7.0.5: Add an implementation_scope
lcartey dd34127
Merge branch 'main' into lcartey/cpp-conversions
lcartey 1cc458b
Rule 7.0.3: Address review feedback
lcartey 51938af
Rule 7.0.1: Address review feedback
lcartey 9bbef6f
Rule 7.0.2: Address review feedback
lcartey b20ea88
Add a utility library for unifying binary ops
lcartey 3e2534b
Move isSigned/isUnsigned to BuiltInTypes
lcartey 1af908a
Rule 7.0.4: Improve reporting
lcartey cd8c960
Rule 7.0.6: Correctly handle constructor exception
lcartey feccaf7
ConstantExpressions: Correct NotExpr to ComplementExpr
lcartey 2c0d06b
Make CanonicalIntegerType singular, use it more widely
lcartey 21cf410
CanonicalTypes: refactor library
lcartey bc7bf51
Rule 7.0.5: Limit to `Cast`s and refactor naming
lcartey f7cd25e
BuiltInTypeRules: Handle bit fields in switch cases
lcartey 2d14c81
Fix CanonicalIntegralType classes
lcartey 9ddf645
BuiltInTypeRules: Rename realType to builtInType
lcartey 8be7b3c
BuiltInTypeRules: Add isSameType API
lcartey bcf8ae9
BuiltInTypeRules: Rename getRealSize to getBuiltInSize
lcartey 94cfcda
MisraType: Avoid misuse of getSize()
lcartey 2c97905
BuiltInTypes: Wrap in MisraCpp23BuiltInTypes module
lcartey 5ca11e9
Add TypeCategory suffix
lcartey 6110770
Update reference to MisraBuiltInTypes
lcartey 8b999e9
BuiltInTypes: Refactor bitfield handling
lcartey 258dadf
Create MISRA arithmetic conversions library
lcartey 3186c70
Test case formatting
lcartey 23be3db
More test case formatting
lcartey 61ae04f
More formatting
lcartey 668e518
Address compilation issue with FunctionType.
lcartey 3575db1
Rule 7.0.2: Use getUnconverted.
lcartey 0b9e2cb
Rule 7.0.2: Treat nullptr_t as a pointer for this rule
lcartey 8d0bb29
Rule 7.0.1: Expand test case to cover non_compliant cases
lcartey 96b644e
Rule 7.0.2: Add extra cast test cases
lcartey 189f8c0
Update expected results after formatting
lcartey 9f46766
Rule 7.0.3: Split unevaluated operands test case
lcartey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import cpp | ||
import codingstandards.cpp.types.Type | ||
|
||
/** | ||
* Gets the `FunctionType` of an expression call. | ||
*/ | ||
FunctionType getExprCallFunctionType(ExprCall call) { | ||
// A standard expression call | ||
// Returns a FunctionPointerIshType | ||
result = call.(ExprCall).getExpr().getType() | ||
or | ||
// An expression call using the pointer to member operator (.* or ->*) | ||
// This special handling is required because we don't have a CodeQL class representing the call | ||
// to a pointer to member function, but the right hand side is extracted as the -1 child of the | ||
// call. | ||
// Returns a RoutineType | ||
result = call.(ExprCall).getChild(-1).getType().(PointerToMemberType).getBaseType() | ||
} |
97 changes: 97 additions & 0 deletions
97
cpp/common/src/codingstandards/cpp/ConstantExpressions.qll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import cpp | ||
|
||
final private class FinalExpr = Expr; | ||
|
||
/** | ||
* An integer constant expression as defined by the C++17 standard. | ||
*/ | ||
class IntegerConstantExpr extends FinalExpr { | ||
lcartey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
IntegerConstantExpr() { | ||
// An integer constant expression is a constant expression that has an | ||
// integral type. | ||
this.isConstant() and | ||
exists(Type unspecifiedType | unspecifiedType = this.getUnspecifiedType() | | ||
unspecifiedType instanceof IntegralType | ||
or | ||
// Unscoped enum type | ||
unspecifiedType instanceof Enum and | ||
not unspecifiedType instanceof ScopedEnum | ||
) | ||
} | ||
|
||
/** | ||
* Gets the value of this integer constant expression. | ||
* | ||
* This is only defined for expressions that are constant expressions, and | ||
* that have a value that can be represented as a `BigInt`. | ||
*/ | ||
QlBuiltins::BigInt getConstantValue() { | ||
if exists(getPreConversionConstantValue()) | ||
then result = getPreConversionConstantValue() | ||
else result = this.getValue().toBigInt() | ||
} | ||
|
||
/** | ||
* Gets the pre-conversion constant value of this integer constant expression, if it is different | ||
* from `getValue()`. | ||
* | ||
* This is required because `Expr.getValue()` returns the _converted constant expression value_ | ||
* for non-literal constant expressions, which is the expression value after conversions have been | ||
* applied, but for validating conversions we need the _pre-conversion constant expression value_. | ||
*/ | ||
private QlBuiltins::BigInt getPreConversionConstantValue() { | ||
// Access of a variable that has a constant initializer | ||
result = | ||
this.(VariableAccess) | ||
.getTarget() | ||
.getInitializer() | ||
.getExpr() | ||
.getFullyConverted() | ||
.getValue() | ||
.toBigInt() | ||
or | ||
result = this.(EnumConstantAccess).getTarget().getValue().toBigInt() | ||
or | ||
result = -this.(UnaryMinusExpr).getOperand().getFullyConverted().getValue().toBigInt() | ||
lcartey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
or | ||
result = this.(UnaryPlusExpr).getOperand().getFullyConverted().getValue().toBigInt() | ||
or | ||
result = this.(NotExpr).getOperand().getFullyConverted().getValue().toBigInt().bitNot() | ||
lcartey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
or | ||
exists(BinaryOperation op, QlBuiltins::BigInt left, QlBuiltins::BigInt right | | ||
op = this and | ||
left = op.getLeftOperand().getFullyConverted().getValue().toBigInt() and | ||
right = op.getRightOperand().getFullyConverted().getValue().toBigInt() | ||
| | ||
op instanceof AddExpr and | ||
result = left + right | ||
or | ||
op instanceof SubExpr and | ||
result = left - right | ||
or | ||
op instanceof MulExpr and | ||
result = left * right | ||
or | ||
op instanceof DivExpr and | ||
result = left / right | ||
or | ||
op instanceof RemExpr and | ||
result = left % right | ||
or | ||
op instanceof BitwiseAndExpr and | ||
result = left.bitAnd(right) | ||
or | ||
op instanceof BitwiseOrExpr and | ||
result = left.bitOr(right) | ||
or | ||
op instanceof BitwiseXorExpr and | ||
result = left.bitXor(right) | ||
or | ||
op instanceof RShiftExpr and | ||
result = left.bitShiftRightSigned(right.toInt()) | ||
or | ||
op instanceof LShiftExpr and | ||
result = left.bitShiftLeft(right.toInt()) | ||
) | ||
} | ||
} |
129 changes: 129 additions & 0 deletions
129
cpp/common/src/codingstandards/cpp/exclusions/cpp/Conversions.qll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ | ||
import cpp | ||
import RuleMetadata | ||
import codingstandards.cpp.exclusions.RuleMetadata | ||
|
||
newtype ConversionsQuery = | ||
TNoConversionFromBoolQuery() or | ||
TNoImplicitBoolConversionQuery() or | ||
TNoCharacterNumericalValueQuery() or | ||
TInappropriateBitwiseOrShiftOperandsQuery() or | ||
TNoSignednessChangeFromPromotionQuery() or | ||
TNumericAssignmentTypeMismatchQuery() or | ||
TFunctionPointerConversionContextQuery() | ||
|
||
predicate isConversionsQueryMetadata(Query query, string queryId, string ruleId, string category) { | ||
query = | ||
// `Query` instance for the `noConversionFromBool` query | ||
ConversionsPackage::noConversionFromBoolQuery() and | ||
queryId = | ||
// `@id` for the `noConversionFromBool` query | ||
"cpp/misra/no-conversion-from-bool" and | ||
ruleId = "RULE-7-0-1" and | ||
category = "required" | ||
or | ||
query = | ||
// `Query` instance for the `noImplicitBoolConversion` query | ||
ConversionsPackage::noImplicitBoolConversionQuery() and | ||
queryId = | ||
// `@id` for the `noImplicitBoolConversion` query | ||
"cpp/misra/no-implicit-bool-conversion" and | ||
ruleId = "RULE-7-0-2" and | ||
category = "required" | ||
or | ||
query = | ||
// `Query` instance for the `noCharacterNumericalValue` query | ||
ConversionsPackage::noCharacterNumericalValueQuery() and | ||
queryId = | ||
// `@id` for the `noCharacterNumericalValue` query | ||
"cpp/misra/no-character-numerical-value" and | ||
ruleId = "RULE-7-0-3" and | ||
category = "required" | ||
or | ||
query = | ||
// `Query` instance for the `inappropriateBitwiseOrShiftOperands` query | ||
ConversionsPackage::inappropriateBitwiseOrShiftOperandsQuery() and | ||
queryId = | ||
// `@id` for the `inappropriateBitwiseOrShiftOperands` query | ||
"cpp/misra/inappropriate-bitwise-or-shift-operands" and | ||
ruleId = "RULE-7-0-4" and | ||
category = "required" | ||
or | ||
query = | ||
// `Query` instance for the `noSignednessChangeFromPromotion` query | ||
ConversionsPackage::noSignednessChangeFromPromotionQuery() and | ||
queryId = | ||
// `@id` for the `noSignednessChangeFromPromotion` query | ||
"cpp/misra/no-signedness-change-from-promotion" and | ||
ruleId = "RULE-7-0-5" and | ||
category = "required" | ||
or | ||
query = | ||
// `Query` instance for the `numericAssignmentTypeMismatch` query | ||
ConversionsPackage::numericAssignmentTypeMismatchQuery() and | ||
queryId = | ||
// `@id` for the `numericAssignmentTypeMismatch` query | ||
"cpp/misra/numeric-assignment-type-mismatch" and | ||
ruleId = "RULE-7-0-6" and | ||
category = "required" | ||
or | ||
query = | ||
// `Query` instance for the `functionPointerConversionContext` query | ||
ConversionsPackage::functionPointerConversionContextQuery() and | ||
queryId = | ||
// `@id` for the `functionPointerConversionContext` query | ||
"cpp/misra/function-pointer-conversion-context" and | ||
ruleId = "RULE-7-11-3" and | ||
category = "required" | ||
} | ||
|
||
module ConversionsPackage { | ||
Query noConversionFromBoolQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `noConversionFromBool` query | ||
TQueryCPP(TConversionsPackageQuery(TNoConversionFromBoolQuery())) | ||
} | ||
|
||
Query noImplicitBoolConversionQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `noImplicitBoolConversion` query | ||
TQueryCPP(TConversionsPackageQuery(TNoImplicitBoolConversionQuery())) | ||
} | ||
|
||
Query noCharacterNumericalValueQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `noCharacterNumericalValue` query | ||
TQueryCPP(TConversionsPackageQuery(TNoCharacterNumericalValueQuery())) | ||
} | ||
|
||
Query inappropriateBitwiseOrShiftOperandsQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `inappropriateBitwiseOrShiftOperands` query | ||
TQueryCPP(TConversionsPackageQuery(TInappropriateBitwiseOrShiftOperandsQuery())) | ||
} | ||
|
||
Query noSignednessChangeFromPromotionQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `noSignednessChangeFromPromotion` query | ||
TQueryCPP(TConversionsPackageQuery(TNoSignednessChangeFromPromotionQuery())) | ||
} | ||
|
||
Query numericAssignmentTypeMismatchQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `numericAssignmentTypeMismatch` query | ||
TQueryCPP(TConversionsPackageQuery(TNumericAssignmentTypeMismatchQuery())) | ||
} | ||
|
||
Query functionPointerConversionContextQuery() { | ||
//autogenerate `Query` type | ||
result = | ||
// `Query` type for `functionPointerConversionContext` query | ||
TQueryCPP(TConversionsPackageQuery(TFunctionPointerConversionContextQuery())) | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef _GHLIBCPP_CWCHAR | ||
#define _GHLIBCPP_CWCHAR | ||
|
||
#include "stddef.h" | ||
|
||
namespace std { | ||
// Character classification and conversion types | ||
typedef struct { | ||
int __count; | ||
union { | ||
unsigned int __wch; | ||
char __wchb[4]; | ||
} __value; | ||
} mbstate_t; | ||
|
||
typedef unsigned int wint_t; | ||
|
||
// Wide character constants | ||
static const wint_t WEOF = static_cast<wint_t>(-1); | ||
|
||
} // namespace std | ||
|
||
#endif // _GHLIBCPP_CWCHAR |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.