-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathDoNotCompareFunctionPointersToConstantValues.ql
85 lines (70 loc) · 2.72 KB
/
DoNotCompareFunctionPointersToConstantValues.ql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* @id c/cert/do-not-compare-function-pointers-to-constant-values
* @name EXP16-C: Do not compare function pointers to constant values
* @description Comparing function pointers to a constant value is not reliable and likely indicates
* a programmer error.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/cert/id/exp16-c
* correctness
* external/cert/obligation/recommendation
*/
import cpp
import codingstandards.c.cert
import codingstandards.cpp.types.FunctionType
import semmle.code.cpp.controlflow.IRGuards
class FunctionExpr extends Expr {
Element function;
string funcName;
FunctionExpr() {
function = this.(FunctionAccess).getTarget() and
funcName = "Function " + function.(Function).getName()
or
this.(VariableAccess).getUnderlyingType() instanceof FunctionType and
function = this and
funcName = "Function pointer variable " + this.(VariableAccess).getTarget().getName()
or
this.getUnderlyingType() instanceof FunctionType and
not this instanceof FunctionAccess and
not this instanceof VariableAccess and
function = this and
funcName = "Expression with function pointer type"
}
Element getFunction() { result = function }
string getFuncName() { result = funcName }
}
abstract class EffectivelyComparison extends Element {
abstract string getExplanation();
abstract FunctionExpr getFunctionExpr();
}
class ExplicitComparison extends EffectivelyComparison, ComparisonOperation {
Expr constantExpr;
FunctionExpr funcExpr;
ExplicitComparison() {
funcExpr = getAnOperand() and
constantExpr = getAnOperand() and
exists(constantExpr.getValue()) and
not funcExpr = constantExpr and
not constantExpr.getExplicitlyConverted().getUnderlyingType() =
funcExpr.getExplicitlyConverted().getUnderlyingType()
}
override string getExplanation() { result = "$@ compared to constant value." }
override FunctionExpr getFunctionExpr() { result = funcExpr }
}
class ImplicitComparison extends EffectivelyComparison, GuardCondition {
ImplicitComparison() {
this instanceof FunctionExpr and
not getParent() instanceof ComparisonOperation
}
override string getExplanation() { result = "$@ undergoes implicit constant comparison." }
override FunctionExpr getFunctionExpr() { result = this }
}
from EffectivelyComparison comparison, FunctionExpr funcExpr, Element function, string funcName
where
not isExcluded(comparison,
Expressions2Package::doNotCompareFunctionPointersToConstantValuesQuery()) and
funcExpr = comparison.getFunctionExpr() and
function = funcExpr.getFunction() and
funcName = funcExpr.getFuncName()
select comparison, comparison.getExplanation(), function, funcName