-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathDoNotCompareFunctionPointersToConstantValues.ql
101 lines (86 loc) · 3.49 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
* @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/rule
*/
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
//from
// EqualityOperation equality, FunctionExpr funcExpr, Element function, string funcName,
// Expr constantExpr
//where
// not isExcluded(equality, Expressions2Package::doNotCompareFunctionPointersToConstantValuesQuery()) and
// funcExpr = equality.getAnOperand() and
// constantExpr = equality.getAnOperand() and
// exists(constantExpr.getValue()) and
// function = funcExpr.getFunction() and
// funcName = funcExpr.getFuncName() and
// constantExpr.getFullyConverted().getUnderlyingType() =
// funcExpr.getFullyConverted().getUnderlyingType()
//select equality,
// "Pointer to function $@ compared to constant value." +
// constantExpr.getFullyConverted().getUnderlyingType().explain() + " / " +
// funcExpr.getFullyConverted().getUnderlyingType().explain(), function, funcName