-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathCallGraph.qll
More file actions
77 lines (69 loc) · 2.11 KB
/
CallGraph.qll
File metadata and controls
77 lines (69 loc) · 2.11 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
import cpp
import semmle.code.cpp.pointsto.PointsTo
// a TargetPointsToExpr has points-to information for expressions
// that will help build an accurate call-graph (i.e. expressions
// in function-pointer calls and qualifiers of virtual calls)
class TargetPointsToExpr extends PointsToExpr {
override predicate interesting() {
exists(ExprCall ec | ec.getExpr() = this)
or
exists(Call c | c.getQualifier() = this)
or
exists(DeleteExpr d | d.getExpr() = this)
}
// resolve a virtual-call where this is the qualifier
VirtualFunction resolve() { pointstosets(this.resolveToSet(), unresolveElement(result)) }
int resolveToSet() {
exists(int cset, VirtualFunction static |
this.interesting() and
parentSetFor(cset, underlyingElement(this)) and
static = this.staticTarget() and
childrenByElement(cset, static, result)
)
}
VirtualFunction staticTarget() {
exists(Function f, DeleteExpr d |
f.calls(result, d) and
d.getExpr() = this
)
or
exists(Function f, FunctionCall c |
f.calls(result, c) and
c.getQualifier() = this
)
}
}
predicate resolvedCall(Call call, Function called) {
call.(FunctionCall).getTarget() = called
or
call.(DestructorCall).getTarget() = called
or
exists(ExprCall ec, TargetPointsToExpr pte |
ec = call and ec.getExpr() = pte and pte.pointsTo() = called
)
or
exists(TargetPointsToExpr pte |
call.getQualifier() = pte and
pte.resolve() = called
)
}
predicate ptrCalls(Function f, Function g) {
exists(ExprCall ec |
ec.getEnclosingFunction() = f and
ec.getExpr().(TargetPointsToExpr).pointsTo() = g
)
}
predicate virtualCalls(Function f, VirtualFunction g) {
exists(DeleteExpr d, TargetPointsToExpr ptexpr, VirtualFunction static |
f.calls(static, d) and
d.getExpr() = ptexpr and
ptexpr.resolve() = g
)
or
exists(Call c, TargetPointsToExpr ptexpr, VirtualFunction static |
f.calls(static, c) and
c.getQualifier() = ptexpr and
ptexpr.resolve() = g
)
}
predicate allCalls(Function f, Function g) { f.calls(g) or ptrCalls(f, g) or virtualCalls(f, g) }