Skip to content

Commit 88b12a5

Browse files
Merge pull request #919 from github/lcartey/cpp-conversions
Implement `Conversions` rule package
2 parents 0f7154e + 9f46766 commit 88b12a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+5436
-45
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import cpp
2+
3+
private signature class BinaryOp extends BinaryOperation;
4+
5+
private signature class AssignBinaryOp extends AssignOperation;
6+
7+
/**
8+
* A module for unifying the `BinaryOperation` and `AssignOperation` hierarchies.
9+
*/
10+
private module BinaryOpUnifier<BinaryOp BinaryOpType, AssignBinaryOp AssignBinaryOpType> {
11+
final class FinalExpr = Expr;
12+
13+
class BinaryExpr extends FinalExpr {
14+
BinaryExpr() {
15+
this instanceof BinaryOpType or
16+
this instanceof AssignBinaryOpType
17+
}
18+
19+
Expr getLeftOperand() {
20+
result = this.(BinaryOpType).getLeftOperand()
21+
or
22+
result = this.(AssignBinaryOpType).getLValue()
23+
}
24+
25+
Expr getRightOperand() {
26+
result = this.(BinaryOpType).getRightOperand()
27+
or
28+
result = this.(AssignBinaryOpType).getRValue()
29+
}
30+
31+
string getOperator() {
32+
result = this.(BinaryOpType).getOperator()
33+
or
34+
result = this.(AssignBinaryOpType).getOperator()
35+
}
36+
}
37+
}
38+
39+
/**
40+
* A binary shift operation (`<<` or `>>`).
41+
*/
42+
class BinaryShiftOperation extends BinaryOperation {
43+
BinaryShiftOperation() {
44+
this instanceof LShiftExpr or
45+
this instanceof RShiftExpr
46+
}
47+
}
48+
49+
/**
50+
* A binary shift assignment operation (`<<=` or `>>=`).
51+
*/
52+
class AssignShiftOperation extends AssignOperation {
53+
AssignShiftOperation() {
54+
this instanceof AssignLShiftExpr or
55+
this instanceof AssignRShiftExpr
56+
}
57+
}
58+
59+
/**
60+
* A binary bitwise operation or binary bitwise assignment operation, including shift operations.
61+
*/
62+
class BinaryBitwiseOpOrAssignOp =
63+
BinaryOpUnifier<BinaryBitwiseOperation, AssignBitwiseOperation>::BinaryExpr;
64+
65+
/**
66+
* A binary shift operation (`<<` or `>>`) or shift assignment operation (`<<=` or `>>=`).
67+
*/
68+
class BinaryShiftOpOrAssignOp =
69+
BinaryOpUnifier<BinaryShiftOperation, AssignShiftOperation>::BinaryExpr;
70+
71+
/**
72+
* A binary arithmetic operation or binary arithmetic assignment operation.
73+
*/
74+
class BinaryArithmeticOpOrAssignOp =
75+
BinaryOpUnifier<BinaryArithmeticOperation, AssignArithmeticOperation>::BinaryExpr;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import cpp
2+
import codingstandards.cpp.types.Type
3+
import codingstandards.cpp.types.FunctionType
4+
5+
/**
6+
* Gets the `FunctionType` of an expression call.
7+
*/
8+
FunctionType getExprCallFunctionType(ExprCall call) {
9+
// A standard expression call
10+
// Returns a FunctionPointerIshType
11+
result = call.(ExprCall).getExpr().getType()
12+
or
13+
// An expression call using the pointer to member operator (.* or ->*)
14+
// This special handling is required because we don't have a CodeQL class representing the call
15+
// to a pointer to member function, but the right hand side is extracted as the -1 child of the
16+
// call.
17+
// Returns a RoutineType
18+
result = call.(ExprCall).getChild(-1).getType().(PointerToMemberType).getBaseType()
19+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import cpp
2+
3+
final private class FinalExpr = Expr;
4+
5+
/**
6+
* An integer constant expression as defined by the C++17 standard.
7+
*/
8+
class IntegerConstantExpr extends FinalExpr {
9+
IntegerConstantExpr() {
10+
// An integer constant expression is a constant expression that has an
11+
// integral type.
12+
this.isConstant() and
13+
exists(Type unspecifiedType | unspecifiedType = this.getUnspecifiedType() |
14+
unspecifiedType instanceof IntegralType
15+
or
16+
// Unscoped enum type
17+
unspecifiedType instanceof Enum and
18+
not unspecifiedType instanceof ScopedEnum
19+
)
20+
}
21+
22+
/**
23+
* Gets the value of this integer constant expression.
24+
*
25+
* This is only defined for expressions that are constant expressions, and
26+
* that have a value that can be represented as a `BigInt`.
27+
*/
28+
QlBuiltins::BigInt getConstantValue() {
29+
if exists(getPreConversionConstantValue())
30+
then result = getPreConversionConstantValue()
31+
else result = this.getValue().toBigInt()
32+
}
33+
34+
/**
35+
* Gets the pre-conversion constant value of this integer constant expression, if it is different
36+
* from `getValue()`.
37+
*
38+
* This is required because `Expr.getValue()` returns the _converted constant expression value_
39+
* for non-literal constant expressions, which is the expression value after conversions have been
40+
* applied, but for validating conversions we need the _pre-conversion constant expression value_.
41+
*/
42+
private QlBuiltins::BigInt getPreConversionConstantValue() {
43+
// Access of a variable that has a constant initializer
44+
result =
45+
this.(VariableAccess)
46+
.getTarget()
47+
.getInitializer()
48+
.getExpr()
49+
.getFullyConverted()
50+
.getValue()
51+
.toBigInt()
52+
or
53+
result = this.(EnumConstantAccess).getTarget().getValue().toBigInt()
54+
or
55+
result = -this.(UnaryMinusExpr).getOperand().getFullyConverted().getValue().toBigInt()
56+
or
57+
result = this.(UnaryPlusExpr).getOperand().getFullyConverted().getValue().toBigInt()
58+
or
59+
result = this.(ComplementExpr).getOperand().getFullyConverted().getValue().toBigInt().bitNot()
60+
or
61+
exists(BinaryOperation op, QlBuiltins::BigInt left, QlBuiltins::BigInt right |
62+
op = this and
63+
left = op.getLeftOperand().getFullyConverted().getValue().toBigInt() and
64+
right = op.getRightOperand().getFullyConverted().getValue().toBigInt()
65+
|
66+
op instanceof AddExpr and
67+
result = left + right
68+
or
69+
op instanceof SubExpr and
70+
result = left - right
71+
or
72+
op instanceof MulExpr and
73+
result = left * right
74+
or
75+
op instanceof DivExpr and
76+
result = left / right
77+
or
78+
op instanceof RemExpr and
79+
result = left % right
80+
or
81+
op instanceof BitwiseAndExpr and
82+
result = left.bitAnd(right)
83+
or
84+
op instanceof BitwiseOrExpr and
85+
result = left.bitOr(right)
86+
or
87+
op instanceof BitwiseXorExpr and
88+
result = left.bitXor(right)
89+
or
90+
op instanceof RShiftExpr and
91+
result = left.bitShiftRightSigned(right.toInt())
92+
or
93+
op instanceof LShiftExpr and
94+
result = left.bitShiftLeft(right.toInt())
95+
)
96+
}
97+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype ConversionsQuery =
7+
TNoConversionFromBoolQuery() or
8+
TNoImplicitBoolConversionQuery() or
9+
TNoCharacterNumericalValueQuery() or
10+
TInappropriateBitwiseOrShiftOperandsQuery() or
11+
TNoSignednessChangeFromPromotionQuery() or
12+
TNumericAssignmentTypeMismatchQuery() or
13+
TFunctionPointerConversionContextQuery()
14+
15+
predicate isConversionsQueryMetadata(Query query, string queryId, string ruleId, string category) {
16+
query =
17+
// `Query` instance for the `noConversionFromBool` query
18+
ConversionsPackage::noConversionFromBoolQuery() and
19+
queryId =
20+
// `@id` for the `noConversionFromBool` query
21+
"cpp/misra/no-conversion-from-bool" and
22+
ruleId = "RULE-7-0-1" and
23+
category = "required"
24+
or
25+
query =
26+
// `Query` instance for the `noImplicitBoolConversion` query
27+
ConversionsPackage::noImplicitBoolConversionQuery() and
28+
queryId =
29+
// `@id` for the `noImplicitBoolConversion` query
30+
"cpp/misra/no-implicit-bool-conversion" and
31+
ruleId = "RULE-7-0-2" and
32+
category = "required"
33+
or
34+
query =
35+
// `Query` instance for the `noCharacterNumericalValue` query
36+
ConversionsPackage::noCharacterNumericalValueQuery() and
37+
queryId =
38+
// `@id` for the `noCharacterNumericalValue` query
39+
"cpp/misra/no-character-numerical-value" and
40+
ruleId = "RULE-7-0-3" and
41+
category = "required"
42+
or
43+
query =
44+
// `Query` instance for the `inappropriateBitwiseOrShiftOperands` query
45+
ConversionsPackage::inappropriateBitwiseOrShiftOperandsQuery() and
46+
queryId =
47+
// `@id` for the `inappropriateBitwiseOrShiftOperands` query
48+
"cpp/misra/inappropriate-bitwise-or-shift-operands" and
49+
ruleId = "RULE-7-0-4" and
50+
category = "required"
51+
or
52+
query =
53+
// `Query` instance for the `noSignednessChangeFromPromotion` query
54+
ConversionsPackage::noSignednessChangeFromPromotionQuery() and
55+
queryId =
56+
// `@id` for the `noSignednessChangeFromPromotion` query
57+
"cpp/misra/no-signedness-change-from-promotion" and
58+
ruleId = "RULE-7-0-5" and
59+
category = "required"
60+
or
61+
query =
62+
// `Query` instance for the `numericAssignmentTypeMismatch` query
63+
ConversionsPackage::numericAssignmentTypeMismatchQuery() and
64+
queryId =
65+
// `@id` for the `numericAssignmentTypeMismatch` query
66+
"cpp/misra/numeric-assignment-type-mismatch" and
67+
ruleId = "RULE-7-0-6" and
68+
category = "required"
69+
or
70+
query =
71+
// `Query` instance for the `functionPointerConversionContext` query
72+
ConversionsPackage::functionPointerConversionContextQuery() and
73+
queryId =
74+
// `@id` for the `functionPointerConversionContext` query
75+
"cpp/misra/function-pointer-conversion-context" and
76+
ruleId = "RULE-7-11-3" and
77+
category = "required"
78+
}
79+
80+
module ConversionsPackage {
81+
Query noConversionFromBoolQuery() {
82+
//autogenerate `Query` type
83+
result =
84+
// `Query` type for `noConversionFromBool` query
85+
TQueryCPP(TConversionsPackageQuery(TNoConversionFromBoolQuery()))
86+
}
87+
88+
Query noImplicitBoolConversionQuery() {
89+
//autogenerate `Query` type
90+
result =
91+
// `Query` type for `noImplicitBoolConversion` query
92+
TQueryCPP(TConversionsPackageQuery(TNoImplicitBoolConversionQuery()))
93+
}
94+
95+
Query noCharacterNumericalValueQuery() {
96+
//autogenerate `Query` type
97+
result =
98+
// `Query` type for `noCharacterNumericalValue` query
99+
TQueryCPP(TConversionsPackageQuery(TNoCharacterNumericalValueQuery()))
100+
}
101+
102+
Query inappropriateBitwiseOrShiftOperandsQuery() {
103+
//autogenerate `Query` type
104+
result =
105+
// `Query` type for `inappropriateBitwiseOrShiftOperands` query
106+
TQueryCPP(TConversionsPackageQuery(TInappropriateBitwiseOrShiftOperandsQuery()))
107+
}
108+
109+
Query noSignednessChangeFromPromotionQuery() {
110+
//autogenerate `Query` type
111+
result =
112+
// `Query` type for `noSignednessChangeFromPromotion` query
113+
TQueryCPP(TConversionsPackageQuery(TNoSignednessChangeFromPromotionQuery()))
114+
}
115+
116+
Query numericAssignmentTypeMismatchQuery() {
117+
//autogenerate `Query` type
118+
result =
119+
// `Query` type for `numericAssignmentTypeMismatch` query
120+
TQueryCPP(TConversionsPackageQuery(TNumericAssignmentTypeMismatchQuery()))
121+
}
122+
123+
Query functionPointerConversionContextQuery() {
124+
//autogenerate `Query` type
125+
result =
126+
// `Query` type for `functionPointerConversionContext` query
127+
TQueryCPP(TConversionsPackageQuery(TFunctionPointerConversionContextQuery()))
128+
}
129+
}

cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Comments
1212
import Concurrency
1313
import Conditionals
1414
import Const
15+
import Conversions
1516
import DeadCode
1617
import Declarations
1718
import ExceptionSafety
@@ -67,6 +68,7 @@ newtype TCPPQuery =
6768
TConcurrencyPackageQuery(ConcurrencyQuery q) or
6869
TConditionalsPackageQuery(ConditionalsQuery q) or
6970
TConstPackageQuery(ConstQuery q) or
71+
TConversionsPackageQuery(ConversionsQuery q) or
7072
TDeadCodePackageQuery(DeadCodeQuery q) or
7173
TDeclarationsPackageQuery(DeclarationsQuery q) or
7274
TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or
@@ -122,6 +124,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
122124
isConcurrencyQueryMetadata(query, queryId, ruleId, category) or
123125
isConditionalsQueryMetadata(query, queryId, ruleId, category) or
124126
isConstQueryMetadata(query, queryId, ruleId, category) or
127+
isConversionsQueryMetadata(query, queryId, ruleId, category) or
125128
isDeadCodeQueryMetadata(query, queryId, ruleId, category) or
126129
isDeclarationsQueryMetadata(query, queryId, ruleId, category) or
127130
isExceptionSafetyQueryMetadata(query, queryId, ruleId, category) or
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import cpp
2+
3+
/**
4+
* One of the 10 canonical integer types, which are the standard integer types.
5+
*/
6+
class CanonicalIntegralType extends IntegralType {
7+
CanonicalIntegralType() { this = this.getCanonicalArithmeticType() }
8+
9+
/**
10+
* Holds if this is the canonical integer type with the shortest name for its size.
11+
*/
12+
predicate isMinimal() {
13+
not exists(CanonicalIntegralType other |
14+
other.getSize() = this.getSize() and
15+
(
16+
other.isSigned() and this.isSigned()
17+
or
18+
other.isUnsigned() and this.isUnsigned()
19+
) and
20+
other.getName().length() < this.getName().length()
21+
)
22+
}
23+
}

cpp/common/src/codingstandards/cpp/types/Compatible.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import cpp
22
import codeql.util.Boolean
33
import codingstandards.cpp.types.Graph
4+
import codingstandards.cpp.types.Type
45
import codingstandards.cpp.types.FunctionType
56

67
module TypeNamesMatchConfig implements TypeEquivalenceSig {
@@ -526,7 +527,6 @@ module FunctionDeclarationTypeEquivalence<
526527
private class LeafType extends Type {
527528
LeafType() {
528529
not this instanceof DerivedType and
529-
not this instanceof FunctionType and
530530
not this instanceof FunctionType
531531
}
532532
}

0 commit comments

Comments
 (0)