Skip to content

Commit 7c5fb87

Browse files
committed
Rule 7.0.6: Address performance issues
- Extract the determination of ExprCall FunctionTypes - Ensure type matching is inlined
1 parent 96d5c1b commit 7c5fb87

File tree

4 files changed

+39
-34
lines changed

4 files changed

+39
-34
lines changed

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

Lines changed: 1 addition & 18 deletions
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

56
module TypeNamesMatchConfig implements TypeEquivalenceSig {
67
predicate resolveTypedefs() {
@@ -522,24 +523,6 @@ module FunctionDeclarationTypeEquivalence<
522523
}
523524
}
524525

525-
/**
526-
* Convenience class to reduce the awkwardness of how `RoutineType` and `FunctionPointerIshType`
527-
* don't have a common ancestor.
528-
*/
529-
private class FunctionType extends Type {
530-
FunctionType() { this instanceof RoutineType or this instanceof FunctionPointerIshType }
531-
532-
Type getReturnType() {
533-
result = this.(RoutineType).getReturnType() or
534-
result = this.(FunctionPointerIshType).getReturnType()
535-
}
536-
537-
Type getParameterType(int i) {
538-
result = this.(RoutineType).getParameterType(i) or
539-
result = this.(FunctionPointerIshType).getParameterType(i)
540-
}
541-
}
542-
543526
private class LeafType extends Type {
544527
LeafType() {
545528
not this instanceof DerivedType and

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,21 @@ predicate integralTypeBounds(IntegralType integralType, QlBuiltins::BigInt lb, Q
111111
)
112112
)
113113
}
114+
115+
/**
116+
* Convenience class to reduce the awkwardness of how `RoutineType` and `FunctionPointerIshType`
117+
* don't have a common ancestor.
118+
*/
119+
class FunctionType extends Type {
120+
FunctionType() { this instanceof RoutineType or this instanceof FunctionPointerIshType }
121+
122+
Type getReturnType() {
123+
result = this.(RoutineType).getReturnType() or
124+
result = this.(FunctionPointerIshType).getReturnType()
125+
}
126+
127+
Type getParameterType(int i) {
128+
result = this.(RoutineType).getParameterType(i) or
129+
result = this.(FunctionPointerIshType).getParameterType(i)
130+
}
131+
}

cpp/misra/src/codingstandards/cpp/misra/BuiltInTypeRules.qll

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ class CanonicalIntegerTypes extends NumericType, IntegralType {
120120
CanonicalIntegerTypes() { this = this.getCanonicalArithmeticType() }
121121
}
122122

123+
FunctionType getExprCallFunctionType(ExprCall call) {
124+
// A standard expression call
125+
// Returns a FunctionPointerIshType
126+
result = call.(ExprCall).getExpr().getType()
127+
or
128+
// An expression call using the pointer to member operator (.* or ->*)
129+
// This special handling is required because we don't have a CodeQL class representing the call
130+
// to a pointer to member function, but the right hand side is extracted as the -1 child of the
131+
// call.
132+
// Returns a RoutineType
133+
result = call.(ExprCall).getChild(-1).getType().(PointerToMemberType).getBaseType()
134+
}
135+
123136
predicate isAssignment(Expr source, NumericType targetType, string context) {
124137
exists(Expr preConversionAssignment |
125138
isPreConversionAssignment(preConversionAssignment, targetType, context) and
@@ -181,27 +194,16 @@ predicate isPreConversionAssignment(Expr source, NumericType targetType, string
181194
not targetType.stripTopLevelSpecifiers() instanceof ReferenceType and
182195
context = "function argument"
183196
|
197+
// A regular function call
184198
targetType = call.getTarget().getParameter(i).getType()
185199
or
186-
// Handle varargs - use the fully converted type of the argument
200+
// A function call where the argument is passed as varargs
187201
call.getTarget().getNumberOfParameters() <= i and
202+
// The rule states that the type should match the "adjusted" type of the argument
188203
targetType = source.getFullyConverted().getType()
189204
or
190-
// A standard expression call
191-
targetType = call.(ExprCall).getExpr().getType().(FunctionPointerIshType).getParameterType(i)
192-
or
193-
// An expression call using the pointer to member operator (.* or ->*)
194-
// This special handling is required because we don't have a CodeQL class representing the call
195-
// to a pointer to member function, but the right hand side is extracted as the -1 child of the
196-
// call
197-
targetType =
198-
call.(ExprCall)
199-
.getChild(-1)
200-
.getType()
201-
.(PointerToMemberType)
202-
.getBaseType()
203-
.(RoutineType)
204-
.getParameterType(i)
205+
// An expression call - get the function type, then the parameter type
206+
targetType = getExprCallFunctionType(call).getParameterType(i)
205207
)
206208
or
207209
// Return statement

cpp/misra/src/rules/RULE-7-0-6/NumericAssignmentTypeMismatch.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ predicate isValidConstantAssignment(IntegerConstantExpr source, NumericType targ
5151
)
5252
}
5353

54+
bindingset[sourceType, targetType]
55+
pragma[inline_late]
5456
predicate isValidTypeMatch(NumericType sourceType, NumericType targetType) {
5557
// Same type category, signedness and size
5658
sourceType.getTypeCategory() = targetType.getTypeCategory() and

0 commit comments

Comments
 (0)