Skip to content

Commit 42f2c88

Browse files
authored
Merge pull request #1 from rdmarsh2/rdmarsh/dataflow/prepare-for-csharp
C++: Use CallInstruction as DataFlowCall
2 parents 5f6e912 + 514d405 commit 42f2c88

File tree

3 files changed

+89
-24
lines changed

3 files changed

+89
-24
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
private import semmle.code.cpp.ir.IR
2+
3+
Function viableImpl(CallInstruction call) { result = viableCallable(call) }
4+
5+
/**
6+
* Gets a function that might be called by `call`.
7+
*/
8+
Function viableCallable(CallInstruction call) {
9+
result = call.getStaticCallTarget()
10+
or
11+
// If the target of the call does not have a body in the snapshot, it might
12+
// be because the target is just a header declaration, and the real target
13+
// will be determined at run time when the caller and callee are linked
14+
// together by the operating system's dynamic linker. In case a _unique_
15+
// function with the right signature is present in the database, we return
16+
// that as a potential callee.
17+
exists(string qualifiedName, int nparams |
18+
callSignatureWithoutBody(qualifiedName, nparams, call) and
19+
functionSignatureWithBody(qualifiedName, nparams, result) and
20+
strictcount(Function other | functionSignatureWithBody(qualifiedName, nparams, other)) = 1
21+
)
22+
}
23+
24+
/**
25+
* Holds if `f` is a function with a body that has name `qualifiedName` and
26+
* `nparams` parameter count. See `functionSignature`.
27+
*/
28+
private predicate functionSignatureWithBody(string qualifiedName, int nparams, Function f) {
29+
functionSignature(f, qualifiedName, nparams) and
30+
exists(f.getBlock())
31+
}
32+
33+
/**
34+
* Holds if the target of `call` is a function _with no definition_ that has
35+
* name `qualifiedName` and `nparams` parameter count. See `functionSignature`.
36+
*/
37+
pragma[noinline]
38+
private predicate callSignatureWithoutBody(string qualifiedName, int nparams, CallInstruction call) {
39+
exists(Function target |
40+
target = call.getStaticCallTarget() and
41+
not exists(target.getBlock()) and
42+
functionSignature(target, qualifiedName, nparams)
43+
)
44+
}
45+
46+
/**
47+
* Holds if `f` has name `qualifiedName` and `nparams` parameter count. This is
48+
* an approximation of its signature for the purpose of matching functions that
49+
* might be the same across link targets.
50+
*/
51+
private predicate functionSignature(Function f, string qualifiedName, int nparams) {
52+
qualifiedName = f.getQualifiedName() and
53+
nparams = f.getNumberOfParameters() and
54+
not f.isStatic()
55+
}
56+
57+
/**
58+
* Holds if the call context `ctx` reduces the set of viable dispatch
59+
* targets of `ma` in `c`.
60+
*/
61+
predicate reducedViableImplInCallContext(CallInstruction call, Function f, CallInstruction ctx) { none() }
62+
63+
/**
64+
* Gets a viable dispatch target of `ma` in the context `ctx`. This is
65+
* restricted to those `ma`s for which the context makes a difference.
66+
*/
67+
Function prunedViableImplInCallContext(CallInstruction call, CallInstruction ctx) { none() }
68+
69+
/**
70+
* Holds if flow returning from `m` to `ma` might return further and if
71+
* this path restricts the set of call sites that can be returned to.
72+
*/
73+
predicate reducedViableImplInReturn(Function f, CallInstruction call) { none() }
74+
75+
/**
76+
* Gets a viable dispatch target of `ma` in the context `ctx`. This is
77+
* restricted to those `ma`s and results for which the return flow from the
78+
* result to `ma` restricts the possible context `ctx`.
79+
*/
80+
Function prunedViableImplInCallContextReverse(CallInstruction call, CallInstruction ctx) { none() }

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplSpecific.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
module Private {
55
import DataFlowPrivate
6-
import semmle.code.cpp.dataflow.internal.DataFlowDispatch
6+
import DataFlowDispatch
77
}
88

99
module Public {

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
private import cpp
22
private import DataFlowUtil
33
private import semmle.code.cpp.ir.IR
4-
private import semmle.code.cpp.dataflow.internal.DataFlowDispatch
4+
private import DataFlowDispatch
55

66
/**
77
* A data flow node that occurs as the argument of a call and is passed as-is
@@ -15,14 +15,9 @@ class ArgumentNode extends Node {
1515
* The instance argument is considered to have index `-1`.
1616
*/
1717
predicate argumentOf(DataFlowCall call, int pos) {
18-
exists(CallInstruction callInstr |
19-
callInstr.getAST() = call and
20-
(
21-
this = callInstr.getPositionalArgument(pos)
22-
or
23-
this = callInstr.getThisArgument() and pos = -1
24-
)
25-
)
18+
this = call.getPositionalArgument(pos)
19+
or
20+
this = call.getThisArgument() and pos = -1
2621
}
2722

2823
/** Gets the call in which this node is an argument. */
@@ -52,11 +47,9 @@ class ReturnNode extends Node {
5247
}
5348

5449
/** A data flow node that represents a call. */
55-
class OutNode extends ExprNode {
56-
OutNode() { this.getExpr() instanceof FunctionCall }
57-
50+
class OutNode extends Node, CallInstruction {
5851
/** Gets the underlying call. */
59-
DataFlowCall getCall() { result = this.getExpr() }
52+
DataFlowCall getCall() { result = this }
6053
}
6154

6255
/** Gets a node that can read the value returned at position `pos`. */
@@ -198,19 +191,11 @@ class DataFlowType = Type;
198191
class DataFlowLocation = Location;
199192

200193
/** A function call relevant for data flow. */
201-
class DataFlowCall extends Expr {
202-
DataFlowCall() { this instanceof Call }
203-
194+
class DataFlowCall extends CallInstruction, Node {
204195
/**
205196
* Gets the nth argument for this call.
206197
*
207198
* The range of `n` is from `0` to `getNumberOfArguments() - 1`.
208199
*/
209-
Expr getArgument(int n) { result = this.(Call).getArgument(n) }
210-
211-
/** Gets the data flow node corresponding to this call. */
212-
ExprNode getNode() { result.getExpr() = this }
213-
214-
/** Gets the enclosing callable of this call. */
215-
Function getEnclosingCallable() { result = this.getEnclosingFunction() }
200+
Node getArgument(int n) { result = this.getPositionalArgument(n) }
216201
}

0 commit comments

Comments
 (0)