-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathFunction.qll
More file actions
81 lines (69 loc) · 2.36 KB
/
Function.qll
File metadata and controls
81 lines (69 loc) · 2.36 KB
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
/** A module to reason about functions, such as well-known functions. */
import cpp
/**
* A function whose name is suggestive that it counts the number of bits set.
*/
class PopCount extends Function {
PopCount() { this.getName().toLowerCase().matches("%popc%nt%") }
}
/**
* A function the user explicitly declared, though its body may be compiler-generated.
*/
class UserDeclaredFunction extends Function {
UserDeclaredFunction() {
not isDeleted() and
(
// Not compiler generated is explicitly declared
not isCompilerGenerated()
or
// Closure functions are compiler generated, but the user
// explicitly declared the lambda expression.
exists(Closure c | c.getLambdaFunction() = this)
or
// Indicates users specifically wrote "= default"
isDefaulted()
)
}
}
/**
* An expression that is effectively a function access.
*
* There are more ways to effectively access a function than a basic `FunctionAcess`, for instance
* taking the address of a function access, and declaring/converting a lambda function.
*/
abstract class FunctionAccessLikeExpr extends Expr {
abstract Function getFunction();
}
/**
* A basic function access expression.
*/
class FunctionAccessExpr extends FunctionAccess, FunctionAccessLikeExpr {
override Function getFunction() { result = this.getTarget() }
}
/**
* Taking an address of a function access in effectively a function access.
*/
class FunctionAddressExpr extends AddressOfExpr, FunctionAccessLikeExpr {
Function func;
FunctionAddressExpr() { func = getOperand().(FunctionAccessLikeExpr).getFunction() }
override Function getFunction() { result = func }
}
/**
* An expression that declares a lambda function is essentially a function access of the lambda
* function body.
*/
class LambdaValueExpr extends LambdaExpression, FunctionAccessLikeExpr {
override Function getFunction() { result = this.(LambdaExpression).getLambdaFunction() }
}
/**
* When a lambda is converted via conversion operator to a function pointer, it is
* effectively a function access of the lambda function.
*/
class LambdaConversionExpr extends FunctionCall, FunctionAccessLikeExpr {
Function func;
LambdaConversionExpr() {
getTarget() instanceof ConversionOperator and
func = getQualifier().(LambdaValueExpr).getFunction()
}
override Function getFunction() { result = func }
}