Skip to content

Commit 3a1836c

Browse files
authored
Merge pull request #7000 from aschackmull/dataflow/interface-refactor
Dataflow: Refactor public references to DataFlowCallable
2 parents 513e0bb + bfacd23 commit 3a1836c

File tree

19 files changed

+93
-62
lines changed

19 files changed

+93
-62
lines changed

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private module Cached {
251251
predicate forceCachingInSameStage() { any() }
252252

253253
cached
254-
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = n.getEnclosingCallable() }
254+
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) }
255255

256256
cached
257257
predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) {
@@ -316,9 +316,7 @@ private module Cached {
316316
}
317317

318318
cached
319-
predicate parameterNode(Node n, DataFlowCallable c, int i) {
320-
n.(ParameterNode).isParameterOf(c, i)
321-
}
319+
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
322320

323321
cached
324322
predicate argumentNode(Node n, DataFlowCall call, int pos) {

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module Consistency {
3131
query predicate uniqueEnclosingCallable(Node n, string msg) {
3232
exists(int c |
3333
n instanceof RelevantNode and
34-
c = count(n.getEnclosingCallable()) and
34+
c = count(nodeGetEnclosingCallable(n)) and
3535
c != 1 and
3636
msg = "Node should have one enclosing callable but has " + c + "."
3737
)
@@ -85,13 +85,13 @@ module Consistency {
8585
}
8686

8787
query predicate parameterCallable(ParameterNode p, string msg) {
88-
exists(DataFlowCallable c | p.isParameterOf(c, _) and c != p.getEnclosingCallable()) and
88+
exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
8989
msg = "Callable mismatch for parameter."
9090
}
9191

9292
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
9393
simpleLocalFlowStep(n1, n2) and
94-
n1.getEnclosingCallable() != n2.getEnclosingCallable() and
94+
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
9595
msg = "Local flow step does not preserve enclosing callable."
9696
}
9797

@@ -106,7 +106,7 @@ module Consistency {
106106
query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
107107
isUnreachableInCall(n, call) and
108108
exists(DataFlowCallable c |
109-
c = n.getEnclosingCallable() and
109+
c = nodeGetEnclosingCallable(n) and
110110
not viableCallable(call) = c
111111
) and
112112
msg = "Call context for isUnreachableInCall is inconsistent with call graph."
@@ -120,7 +120,7 @@ module Consistency {
120120
n.(ArgumentNode).argumentOf(call, _) and
121121
msg = "ArgumentNode and call does not share enclosing callable."
122122
) and
123-
n.getEnclosingCallable() != call.getEnclosingCallable()
123+
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
124124
}
125125

126126
// This predicate helps the compiler forget that in some languages
@@ -151,7 +151,7 @@ module Consistency {
151151
}
152152

153153
query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
154-
n.getEnclosingCallable() != n.getPreUpdateNode().getEnclosingCallable() and
154+
nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
155155
msg = "PostUpdateNode does not share callable with its pre-update node."
156156
}
157157

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ private import DataFlowUtil
33
private import DataFlowDispatch
44
private import FlowVar
55

6+
/** Gets the callable in which this node occurs. */
7+
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
8+
9+
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
10+
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { p.isParameterOf(c, pos) }
11+
612
/** Gets the instance argument of a non-static call. */
713
private Node getInstanceArgument(Call call) {
814
result.asExpr() = call.getQualifier()

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private module Cached {
251251
predicate forceCachingInSameStage() { any() }
252252

253253
cached
254-
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = n.getEnclosingCallable() }
254+
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) }
255255

256256
cached
257257
predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) {
@@ -316,9 +316,7 @@ private module Cached {
316316
}
317317

318318
cached
319-
predicate parameterNode(Node n, DataFlowCallable c, int i) {
320-
n.(ParameterNode).isParameterOf(c, i)
321-
}
319+
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
322320

323321
cached
324322
predicate argumentNode(Node n, DataFlowCall call, int pos) {

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module Consistency {
3131
query predicate uniqueEnclosingCallable(Node n, string msg) {
3232
exists(int c |
3333
n instanceof RelevantNode and
34-
c = count(n.getEnclosingCallable()) and
34+
c = count(nodeGetEnclosingCallable(n)) and
3535
c != 1 and
3636
msg = "Node should have one enclosing callable but has " + c + "."
3737
)
@@ -85,13 +85,13 @@ module Consistency {
8585
}
8686

8787
query predicate parameterCallable(ParameterNode p, string msg) {
88-
exists(DataFlowCallable c | p.isParameterOf(c, _) and c != p.getEnclosingCallable()) and
88+
exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
8989
msg = "Callable mismatch for parameter."
9090
}
9191

9292
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
9393
simpleLocalFlowStep(n1, n2) and
94-
n1.getEnclosingCallable() != n2.getEnclosingCallable() and
94+
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
9595
msg = "Local flow step does not preserve enclosing callable."
9696
}
9797

@@ -106,7 +106,7 @@ module Consistency {
106106
query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
107107
isUnreachableInCall(n, call) and
108108
exists(DataFlowCallable c |
109-
c = n.getEnclosingCallable() and
109+
c = nodeGetEnclosingCallable(n) and
110110
not viableCallable(call) = c
111111
) and
112112
msg = "Call context for isUnreachableInCall is inconsistent with call graph."
@@ -120,7 +120,7 @@ module Consistency {
120120
n.(ArgumentNode).argumentOf(call, _) and
121121
msg = "ArgumentNode and call does not share enclosing callable."
122122
) and
123-
n.getEnclosingCallable() != call.getEnclosingCallable()
123+
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
124124
}
125125

126126
// This predicate helps the compiler forget that in some languages
@@ -151,7 +151,7 @@ module Consistency {
151151
}
152152

153153
query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
154-
n.getEnclosingCallable() != n.getPreUpdateNode().getEnclosingCallable() and
154+
nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
155155
msg = "PostUpdateNode does not share callable with its pre-update node."
156156
}
157157

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ private import DataFlowUtil
33
private import semmle.code.cpp.ir.IR
44
private import DataFlowDispatch
55

6+
/** Gets the callable in which this node occurs. */
7+
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
8+
9+
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
10+
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { p.isParameterOf(c, pos) }
11+
612
/**
713
* A data flow node that occurs as the argument of a call and is passed as-is
814
* to the callable. Instance arguments (`this` pointer) and read side effects

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private module Cached {
251251
predicate forceCachingInSameStage() { any() }
252252

253253
cached
254-
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = n.getEnclosingCallable() }
254+
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) }
255255

256256
cached
257257
predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) {
@@ -316,9 +316,7 @@ private module Cached {
316316
}
317317

318318
cached
319-
predicate parameterNode(Node n, DataFlowCallable c, int i) {
320-
n.(ParameterNode).isParameterOf(c, i)
321-
}
319+
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
322320

323321
cached
324322
predicate argumentNode(Node n, DataFlowCall call, int pos) {

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module Consistency {
3131
query predicate uniqueEnclosingCallable(Node n, string msg) {
3232
exists(int c |
3333
n instanceof RelevantNode and
34-
c = count(n.getEnclosingCallable()) and
34+
c = count(nodeGetEnclosingCallable(n)) and
3535
c != 1 and
3636
msg = "Node should have one enclosing callable but has " + c + "."
3737
)
@@ -85,13 +85,13 @@ module Consistency {
8585
}
8686

8787
query predicate parameterCallable(ParameterNode p, string msg) {
88-
exists(DataFlowCallable c | p.isParameterOf(c, _) and c != p.getEnclosingCallable()) and
88+
exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
8989
msg = "Callable mismatch for parameter."
9090
}
9191

9292
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
9393
simpleLocalFlowStep(n1, n2) and
94-
n1.getEnclosingCallable() != n2.getEnclosingCallable() and
94+
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
9595
msg = "Local flow step does not preserve enclosing callable."
9696
}
9797

@@ -106,7 +106,7 @@ module Consistency {
106106
query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
107107
isUnreachableInCall(n, call) and
108108
exists(DataFlowCallable c |
109-
c = n.getEnclosingCallable() and
109+
c = nodeGetEnclosingCallable(n) and
110110
not viableCallable(call) = c
111111
) and
112112
msg = "Call context for isUnreachableInCall is inconsistent with call graph."
@@ -120,7 +120,7 @@ module Consistency {
120120
n.(ArgumentNode).argumentOf(call, _) and
121121
msg = "ArgumentNode and call does not share enclosing callable."
122122
) and
123-
n.getEnclosingCallable() != call.getEnclosingCallable()
123+
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
124124
}
125125

126126
// This predicate helps the compiler forget that in some languages
@@ -151,7 +151,7 @@ module Consistency {
151151
}
152152

153153
query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
154-
n.getEnclosingCallable() != n.getPreUpdateNode().getEnclosingCallable() and
154+
nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
155155
msg = "PostUpdateNode does not share callable with its pre-update node."
156156
}
157157

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ private import semmle.code.csharp.frameworks.NHibernate
1818
private import semmle.code.csharp.frameworks.system.Collections
1919
private import semmle.code.csharp.frameworks.system.threading.Tasks
2020

21+
/** Gets the callable in which this node occurs. */
22+
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
23+
24+
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
25+
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { p.isParameterOf(c, pos) }
26+
2127
abstract class NodeImpl extends Node {
2228
/** Do not call: use `getEnclosingCallable()` instead. */
2329
abstract DataFlowCallable getEnclosingCallableImpl();

docs/ql-libraries/dataflow/dataflow.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,19 @@ call-graph should be defined as a predicate:
150150
```ql
151151
DataFlowCallable viableCallable(DataFlowCall c)
152152
```
153+
Furthermore, each `Node` must be associated with exactly one callable and this
154+
relation should be defined as:
155+
```ql
156+
DataFlowCallable nodeGetEnclosingCallable(Node n)
157+
```
153158

154159
In order to connect data-flow across calls, the 4 `Node` subclasses
155160
`ArgumentNode`, `ParameterNode`, `ReturnNode`, and `OutNode` are used.
156161
Flow into callables from arguments to parameters are matched up using an
157-
integer position, so these two classes must define:
162+
integer position, so these two predicates must be defined:
158163
```ql
159164
ArgumentNode::argumentOf(DataFlowCall call, int pos)
160-
ParameterNode::isParameterOf(DataFlowCallable c, int pos)
165+
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos)
161166
```
162167
It is typical to use `pos = -1` for an implicit `this`-parameter.
163168

0 commit comments

Comments
 (0)