Files
codeql/cpp/ql/lib/semmle/code/cpp/pointsto/CallGraph.qll
Andrew Eisenberg 2c5dd2dfa3 Packaging: Refactor the cpp libraries
This PR separates the core cpp packs into `codeql/cpp-queries` and
`codeql/cpp-all`.

There are very few lines of code changed. Almost all changes are moving
files around.
2021-08-17 11:22:36 -07:00

78 lines
2.1 KiB
Plaintext

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) }