Skip to content

Commit 4ea9998

Browse files
authored
Merge pull request #1746 from jbj/ast-field-flow-ctor
C++: Field flow through ConstructorFieldInit
2 parents 4dc460b + ee8c0cb commit 4ea9998

File tree

10 files changed

+141
-13
lines changed

10 files changed

+141
-13
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
186186
node2.getPreUpdateNode().asExpr() = fa.getQualifier() and
187187
f.(FieldContent).getField() = fa.getTarget()
188188
)
189+
or
190+
exists(ConstructorFieldInit cfi |
191+
node2.getPreUpdateNode().(PreConstructorInitThis).getConstructorFieldInit() = cfi and
192+
f.(FieldContent).getField() = cfi.getTarget() and
193+
node1.asExpr() = cfi.getExpr()
194+
)
189195
}
190196

191197
/**

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ private newtype TNode =
1717
} or
1818
TExplicitParameterNode(Parameter p) { exists(p.getFunction().getBlock()) } or
1919
TInstanceParameterNode(MemberFunction f) { exists(f.getBlock()) and not f.isStatic() } or
20+
TPreConstructorInitThis(ConstructorFieldInit cfi) or
21+
TPostConstructorInitThis(ConstructorFieldInit cfi) or
2022
TUninitializedNode(LocalVariable v) { not v.hasInitializer() }
2123

2224
/**
@@ -300,6 +302,44 @@ class PreObjectInitializerNode extends Node, TPreObjectInitializerNode {
300302
override string toString() { result = getExpr().toString() + " [pre init]" }
301303
}
302304

305+
/**
306+
* A synthetic data-flow node that plays the role of the post-update `this`
307+
* pointer in a `ConstructorFieldInit`. For example, the `x(1)` in
308+
* `C() : x(1) { }` is roughly equivalent to `this.x = 1`, and this node is
309+
* equivalent to the `this` _after_ the field has been assigned.
310+
*/
311+
private class PostConstructorInitThis extends PostUpdateNode, TPostConstructorInitThis {
312+
override PreConstructorInitThis getPreUpdateNode() {
313+
this = TPostConstructorInitThis(result.getConstructorFieldInit())
314+
}
315+
316+
override string toString() {
317+
result = getPreUpdateNode().getConstructorFieldInit().toString() + " [post-this]"
318+
}
319+
}
320+
321+
/**
322+
* INTERNAL: do not use.
323+
*
324+
* A synthetic data-flow node that plays the role of the pre-update `this`
325+
* pointer in a `ConstructorFieldInit`. For example, the `x(1)` in
326+
* `C() : x(1) { }` is roughly equivalent to `this.x = 1`, and this node is
327+
* equivalent to the `this` _before_ the field has been assigned.
328+
*/
329+
class PreConstructorInitThis extends Node, TPreConstructorInitThis {
330+
ConstructorFieldInit getConstructorFieldInit() { this = TPreConstructorInitThis(result) }
331+
332+
override Constructor getFunction() { result = getConstructorFieldInit().getEnclosingFunction() }
333+
334+
override PointerType getType() {
335+
result.getBaseType() = getConstructorFieldInit().getEnclosingFunction().getDeclaringType()
336+
}
337+
338+
override Location getLocation() { result = getConstructorFieldInit().getLocation() }
339+
340+
override string toString() { result = getConstructorFieldInit().toString() + " [pre-this]" }
341+
}
342+
303343
/**
304344
* Gets the `Node` corresponding to `e`.
305345
*/
@@ -325,17 +365,34 @@ DefinitionByReferenceNode definitionByReferenceNodeFromArgument(Expr argument) {
325365
UninitializedNode uninitializedNode(LocalVariable v) { result.getLocalVariable() = v }
326366

327367
private module ThisFlow {
328-
private Node thisAccessNode(ControlFlowNode cfn) {
329-
result.(ImplicitParameterNode).getFunction().getBlock() = cfn or
330-
result.asExpr().(ThisExpr) = cfn
331-
}
332-
368+
/**
369+
* Gets the 0-based index of `thisNode` in `b`, where `thisNode` is an access
370+
* to `this` that may or may not have an associated `PostUpdateNode`. To make
371+
* room for synthetic nodes that access `this`, the index may not correspond
372+
* to an actual `ControlFlowNode`.
373+
*/
333374
private int basicBlockThisIndex(BasicBlock b, Node thisNode) {
334-
thisNode = thisAccessNode(b.getNode(result))
375+
// The implicit `this` parameter node is given a very negative offset to
376+
// make space for any `ConstructorFieldInit`s there may be between it and
377+
// the block contents.
378+
thisNode.(ImplicitParameterNode).getFunction().getBlock() = b and
379+
result = -2147483648
380+
or
381+
// Place the synthetic `this` node for a `ConstructorFieldInit` at a
382+
// negative offset in the first basic block, between the
383+
// `ImplicitParameterNode` and the first statement.
384+
exists(Constructor constructor, int i |
385+
thisNode.(PreConstructorInitThis).getConstructorFieldInit() =
386+
constructor.getInitializer(i) and
387+
result = -2147483648 + 1 + i and
388+
b = thisNode.getFunction().getBlock()
389+
)
390+
or
391+
b.getNode(result) = thisNode.asExpr().(ThisExpr)
335392
}
336393

337394
private int thisRank(BasicBlock b, Node thisNode) {
338-
thisNode = rank[result](thisAccessNode(_) as node order by basicBlockThisIndex(b, node))
395+
thisNode = rank[result](Node n, int i | i = basicBlockThisIndex(b, n) | n order by i)
339396
}
340397

341398
private int lastThisRank(BasicBlock b) { result = max(thisRank(b, _)) }

cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ module FlowVar_internal {
249249
result = descendentDef.getAUse(v)
250250
)
251251
)
252+
or
253+
parameterUsedInConstructorFieldInit(v, result) and
254+
def.definedByParameter(v)
252255
}
253256

254257
override predicate definedByExpr(Expr e, ControlFlowNode node) {
@@ -314,6 +317,9 @@ module FlowVar_internal {
314317
override VariableAccess getAnAccess() {
315318
variableAccessInSBB(v, getAReachedBlockVarSBB(this), result) and
316319
result != sbb
320+
or
321+
parameterUsedInConstructorFieldInit(v, result) and
322+
sbb = v.(Parameter).getFunction().getEntryPoint()
317323
}
318324

319325
override predicate definedByInitialValue(LocalScopeVariable lsv) {
@@ -692,6 +698,21 @@ module FlowVar_internal {
692698
assignedExpr = init.getExpr()
693699
}
694700

701+
/**
702+
* Holds if `p` is a parameter to a constructor that is used in a
703+
* `ConstructorFieldInit` at `va`. This ignores the corner case that `p`
704+
* might have been overwritten to have a different value before this happens.
705+
*/
706+
predicate parameterUsedInConstructorFieldInit(Parameter p, VariableAccess va) {
707+
exists(Constructor constructor |
708+
constructor.getInitializer(_).(ConstructorFieldInit).getExpr().getAChild*() = va and
709+
va = p.getAnAccess()
710+
// We don't require that `constructor` has `p` as a parameter because
711+
// that follows from the two other conditions and would likely just
712+
// confuse the join orderer.
713+
)
714+
}
715+
695716
/**
696717
* A point in a basic block where a non-SSA variable may have a different value
697718
* than it did elsewhere in the same basic block. Extending this class

cpp/ql/test/library-tests/dataflow/fields/C.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class C
2626

2727
void func()
2828
{
29-
sink(s1); // flow [NOT DETECTED] (in either place)
29+
sink(s1); // flow
3030
sink(s2); // flow [NOT DETECTED]
3131
sink(s3); // flow
3232
sink(s4); // flow [NOT DETECTED]

cpp/ql/test/library-tests/dataflow/fields/constructors.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ class Foo
2525

2626
void bar(Foo &f)
2727
{
28-
sink(f.a()); // flow (through `f` and `h`) [NOT DETECTED]
29-
sink(f.b()); // flow (through `g` and `h`) [NOT DETECTED]
28+
sink(f.a()); // flow (through `f` and `h`)
29+
sink(f.b()); // flow (through `g` and `h`)
3030
}
3131

3232
void foo()

cpp/ql/test/library-tests/dataflow/fields/flow.expected

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,34 @@ edges
7575
| B.cpp:18:14:18:17 | box1 [elem1, ... (1)] | B.cpp:18:20:18:24 | elem1 |
7676
| B.cpp:19:10:19:11 | b2 [box1, ... (2)] | B.cpp:19:14:19:17 | box1 [elem2, ... (1)] |
7777
| B.cpp:19:14:19:17 | box1 [elem2, ... (1)] | B.cpp:19:20:19:24 | elem2 |
78+
| C.cpp:18:12:18:18 | call to C [s1, ... (1)] | C.cpp:19:5:19:5 | c [s1, ... (1)] |
7879
| C.cpp:18:12:18:18 | call to C [s3, ... (1)] | C.cpp:19:5:19:5 | c [s3, ... (1)] |
80+
| C.cpp:19:5:19:5 | c [s1, ... (1)] | C.cpp:27:8:27:11 | `this` parameter in func [s1, ... (1)] |
7981
| C.cpp:19:5:19:5 | c [s3, ... (1)] | C.cpp:27:8:27:11 | `this` parameter in func [s3, ... (1)] |
82+
| C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1, ... (1)] | C.cpp:18:12:18:18 | call to C [s1, ... (1)] |
83+
| C.cpp:22:12:22:21 | new [void] | C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1, ... (1)] |
8084
| C.cpp:24:5:24:8 | this [post update] [s3, ... (1)] | C.cpp:18:12:18:18 | call to C [s3, ... (1)] |
8185
| C.cpp:24:5:24:25 | ... = ... [void] | C.cpp:24:5:24:8 | this [post update] [s3, ... (1)] |
8286
| C.cpp:24:16:24:25 | new [void] | C.cpp:24:5:24:25 | ... = ... [void] |
87+
| C.cpp:27:8:27:11 | `this` parameter in func [s1, ... (1)] | file://:0:0:0:0 | this [s1, ... (1)] |
8388
| C.cpp:27:8:27:11 | `this` parameter in func [s3, ... (1)] | file://:0:0:0:0 | this [s3, ... (1)] |
89+
| constructors.cpp:26:15:26:15 | f [a_, ... (1)] | constructors.cpp:28:10:28:10 | f [a_, ... (1)] |
90+
| constructors.cpp:26:15:26:15 | f [b_, ... (1)] | constructors.cpp:29:10:29:10 | f [b_, ... (1)] |
91+
| constructors.cpp:28:10:28:10 | f [a_, ... (1)] | constructors.cpp:28:12:28:12 | call to a |
92+
| constructors.cpp:29:10:29:10 | f [b_, ... (1)] | constructors.cpp:29:12:29:12 | call to b |
93+
| constructors.cpp:34:11:34:20 | call to user_input [void] | constructors.cpp:34:11:34:26 | call to Foo [a_, ... (1)] |
94+
| constructors.cpp:34:11:34:26 | call to Foo [a_, ... (1)] | constructors.cpp:40:9:40:9 | f [a_, ... (1)] |
95+
| constructors.cpp:35:11:35:26 | call to Foo [b_, ... (1)] | constructors.cpp:43:9:43:9 | g [b_, ... (1)] |
96+
| constructors.cpp:35:14:35:23 | call to user_input [void] | constructors.cpp:35:11:35:26 | call to Foo [b_, ... (1)] |
97+
| constructors.cpp:36:11:36:20 | call to user_input [void] | constructors.cpp:36:11:36:37 | call to Foo [a_, ... (1)] |
98+
| constructors.cpp:36:11:36:37 | call to Foo [a_, ... (1)] | constructors.cpp:46:9:46:9 | h [a_, ... (1)] |
99+
| constructors.cpp:36:11:36:37 | call to Foo [b_, ... (1)] | constructors.cpp:46:9:46:9 | h [b_, ... (1)] |
100+
| constructors.cpp:36:25:36:34 | call to user_input [void] | constructors.cpp:36:11:36:37 | call to Foo [b_, ... (1)] |
101+
| constructors.cpp:40:9:40:9 | f [a_, ... (1)] | constructors.cpp:26:15:26:15 | f [a_, ... (1)] |
102+
| constructors.cpp:43:9:43:9 | g [b_, ... (1)] | constructors.cpp:26:15:26:15 | f [b_, ... (1)] |
103+
| constructors.cpp:46:9:46:9 | h [a_, ... (1)] | constructors.cpp:26:15:26:15 | f [a_, ... (1)] |
104+
| constructors.cpp:46:9:46:9 | h [b_, ... (1)] | constructors.cpp:26:15:26:15 | f [b_, ... (1)] |
105+
| file://:0:0:0:0 | this [s1, ... (1)] | C.cpp:29:10:29:11 | s1 |
84106
| file://:0:0:0:0 | this [s3, ... (1)] | C.cpp:31:10:31:11 | s3 |
85107
| simple.cpp:26:15:26:15 | f [a_, ... (1)] | simple.cpp:28:10:28:10 | f [a_, ... (1)] |
86108
| simple.cpp:26:15:26:15 | f [b_, ... (1)] | simple.cpp:29:10:29:10 | f [b_, ... (1)] |
@@ -124,7 +146,12 @@ edges
124146
| B.cpp:10:20:10:24 | elem2 | B.cpp:6:15:6:24 | new [void] | B.cpp:10:20:10:24 | elem2 | elem2 flows from $@ | B.cpp:6:15:6:24 | new [void] | new [void] |
125147
| B.cpp:18:20:18:24 | elem1 | B.cpp:15:15:15:27 | new [void] | B.cpp:18:20:18:24 | elem1 | elem1 flows from $@ | B.cpp:15:15:15:27 | new [void] | new [void] |
126148
| B.cpp:19:20:19:24 | elem2 | B.cpp:15:15:15:27 | new [void] | B.cpp:19:20:19:24 | elem2 | elem2 flows from $@ | B.cpp:15:15:15:27 | new [void] | new [void] |
149+
| C.cpp:29:10:29:11 | s1 | C.cpp:22:12:22:21 | new [void] | C.cpp:29:10:29:11 | s1 | s1 flows from $@ | C.cpp:22:12:22:21 | new [void] | new [void] |
127150
| C.cpp:31:10:31:11 | s3 | C.cpp:24:16:24:25 | new [void] | C.cpp:31:10:31:11 | s3 | s3 flows from $@ | C.cpp:24:16:24:25 | new [void] | new [void] |
151+
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input [void] | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input [void] | call to user_input [void] |
152+
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input [void] | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input [void] | call to user_input [void] |
153+
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input [void] | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input [void] | call to user_input [void] |
154+
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:36:25:36:34 | call to user_input [void] | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:36:25:36:34 | call to user_input [void] | call to user_input [void] |
128155
| simple.cpp:28:12:28:12 | call to a | simple.cpp:39:12:39:21 | call to user_input [void] | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:39:12:39:21 | call to user_input [void] | call to user_input [void] |
129156
| simple.cpp:28:12:28:12 | call to a | simple.cpp:41:12:41:21 | call to user_input [void] | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:41:12:41:21 | call to user_input [void] | call to user_input [void] |
130157
| simple.cpp:29:12:29:12 | call to b | simple.cpp:40:12:40:21 | call to user_input [void] | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:40:12:40:21 | call to user_input [void] | call to user_input [void] |

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@
6262
| taint.cpp:37:12:37:20 | call to increment | taint.cpp:43:7:43:13 | global9 | |
6363
| taint.cpp:38:13:38:16 | call to zero | taint.cpp:38:2:38:26 | ... = ... | |
6464
| taint.cpp:38:13:38:16 | call to zero | taint.cpp:44:7:44:14 | global10 | |
65-
| taint.cpp:71:2:71:8 | `this` parameter in MyClass | file://:0:0:0:0 | this | |
65+
| taint.cpp:71:2:71:8 | `this` parameter in MyClass | taint.cpp:71:14:71:17 | constructor init of field a [pre-this] | |
6666
| taint.cpp:71:14:71:17 | 0 | taint.cpp:71:14:71:17 | constructor init of field a | TAINT |
67+
| taint.cpp:71:14:71:17 | constructor init of field a [post-this] | taint.cpp:71:20:71:30 | constructor init of field b [pre-this] | |
68+
| taint.cpp:71:14:71:17 | constructor init of field a [pre-this] | taint.cpp:71:20:71:30 | constructor init of field b [pre-this] | |
69+
| taint.cpp:71:20:71:30 | constructor init of field b [post-this] | file://:0:0:0:0 | this | |
70+
| taint.cpp:71:20:71:30 | constructor init of field b [pre-this] | file://:0:0:0:0 | this | |
6771
| taint.cpp:71:22:71:27 | call to source | taint.cpp:71:20:71:30 | constructor init of field b | TAINT |
6872
| taint.cpp:72:3:72:3 | this [post update] | file://:0:0:0:0 | this | |
6973
| taint.cpp:72:7:72:12 | call to source | taint.cpp:72:3:72:14 | ... = ... | |
@@ -212,6 +216,8 @@
212216
| taint.cpp:226:9:226:10 | 0 | taint.cpp:261:7:261:7 | w | |
213217
| taint.cpp:228:11:228:11 | Unknown literal | taint.cpp:228:11:228:11 | constructor init of field t | TAINT |
214218
| taint.cpp:228:11:228:11 | Unknown literal | taint.cpp:228:11:228:11 | constructor init of field u | TAINT |
219+
| taint.cpp:228:11:228:11 | `this` parameter in (constructor) | taint.cpp:228:11:228:11 | constructor init of field t [pre-this] | |
220+
| taint.cpp:228:11:228:11 | `this` parameter in (constructor) | taint.cpp:243:11:243:11 | constructor init of field t [pre-this] | |
215221
| taint.cpp:228:11:232:2 | [...](...){...} | taint.cpp:233:7:233:7 | a | |
216222
| taint.cpp:228:11:232:2 | {...} | taint.cpp:228:11:232:2 | [...](...){...} | |
217223
| taint.cpp:228:12:228:12 | t | taint.cpp:228:11:232:2 | {...} | TAINT |
@@ -221,12 +227,19 @@
221227
| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field t | TAINT |
222228
| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field u | TAINT |
223229
| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field v | TAINT |
230+
| taint.cpp:235:11:235:11 | `this` parameter in (constructor) | taint.cpp:235:11:235:11 | constructor init of field t [pre-this] | |
231+
| taint.cpp:235:11:235:11 | constructor init of field t [post-this] | taint.cpp:235:11:235:11 | constructor init of field u [pre-this] | |
232+
| taint.cpp:235:11:235:11 | constructor init of field t [pre-this] | taint.cpp:235:11:235:11 | constructor init of field u [pre-this] | |
233+
| taint.cpp:235:11:235:11 | constructor init of field u [post-this] | taint.cpp:235:11:235:11 | constructor init of field v [pre-this] | |
234+
| taint.cpp:235:11:235:11 | constructor init of field u [pre-this] | taint.cpp:235:11:235:11 | constructor init of field v [pre-this] | |
224235
| taint.cpp:235:11:239:2 | [...](...){...} | taint.cpp:240:2:240:2 | b | |
225236
| taint.cpp:235:11:239:2 | {...} | taint.cpp:235:11:239:2 | [...](...){...} | |
226237
| taint.cpp:235:15:235:15 | `this` parameter in operator() | file://:0:0:0:0 | this | |
227238
| taint.cpp:238:7:238:12 | call to source | taint.cpp:238:3:238:14 | ... = ... | |
228239
| taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field t | TAINT |
229240
| taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field u | TAINT |
241+
| taint.cpp:243:11:243:11 | `this` parameter in (constructor) | taint.cpp:228:11:228:11 | constructor init of field t [pre-this] | |
242+
| taint.cpp:243:11:243:11 | `this` parameter in (constructor) | taint.cpp:243:11:243:11 | constructor init of field t [pre-this] | |
230243
| taint.cpp:243:11:246:2 | [...](...){...} | taint.cpp:247:2:247:2 | c | |
231244
| taint.cpp:243:11:246:2 | {...} | taint.cpp:243:11:246:2 | [...](...){...} | |
232245
| taint.cpp:243:15:243:15 | `this` parameter in operator() | file://:0:0:0:0 | this | |

cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ void class_field_test() {
8686
mc1.myMethod();
8787

8888
sink(mc1.a);
89-
sink(mc1.b); // tainted [NOT DETECTED]
89+
sink(mc1.b); // tainted [NOT DETECTED with IR]
9090
sink(mc1.c); // tainted [NOT DETECTED with IR]
9191
sink(mc1.d); // tainted [NOT DETECTED with IR]
9292
sink(mc2.a);
93-
sink(mc2.b); // tainted [NOT DETECTED]
93+
sink(mc2.b); // tainted [NOT DETECTED with IR]
9494
sink(mc2.c); // tainted [NOT DETECTED with IR]
9595
sink(mc2.d);
9696
}

cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
| taint.cpp:41:7:41:13 | global7 | taint.cpp:35:12:35:17 | call to source |
1111
| taint.cpp:42:7:42:13 | global8 | taint.cpp:35:12:35:17 | call to source |
1212
| taint.cpp:43:7:43:13 | global9 | taint.cpp:37:22:37:27 | call to source |
13+
| taint.cpp:89:11:89:11 | b | taint.cpp:71:22:71:27 | call to source |
1314
| taint.cpp:90:11:90:11 | c | taint.cpp:72:7:72:12 | call to source |
1415
| taint.cpp:91:11:91:11 | d | taint.cpp:77:7:77:12 | call to source |
16+
| taint.cpp:93:11:93:11 | b | taint.cpp:71:22:71:27 | call to source |
1517
| taint.cpp:94:11:94:11 | c | taint.cpp:72:7:72:12 | call to source |
1618
| taint.cpp:129:7:129:9 | * ... | taint.cpp:120:11:120:16 | call to source |
1719
| taint.cpp:134:7:134:9 | * ... | taint.cpp:120:11:120:16 | call to source |

cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
| taint.cpp:41:7:41:13 | taint.cpp:35:12:35:17 | AST only |
33
| taint.cpp:42:7:42:13 | taint.cpp:35:12:35:17 | AST only |
44
| taint.cpp:43:7:43:13 | taint.cpp:37:22:37:27 | AST only |
5+
| taint.cpp:89:11:89:11 | taint.cpp:71:22:71:27 | AST only |
56
| taint.cpp:90:11:90:11 | taint.cpp:72:7:72:12 | AST only |
67
| taint.cpp:91:11:91:11 | taint.cpp:77:7:77:12 | AST only |
8+
| taint.cpp:93:11:93:11 | taint.cpp:71:22:71:27 | AST only |
79
| taint.cpp:94:11:94:11 | taint.cpp:72:7:72:12 | AST only |
810
| taint.cpp:130:7:130:9 | taint.cpp:127:8:127:13 | IR only |
911
| taint.cpp:137:7:137:9 | taint.cpp:120:11:120:16 | AST only |

0 commit comments

Comments
 (0)