Skip to content

Commit 44e32a6

Browse files
committed
C++: Restore the missing flow. This has a couple of
side-effects: First, It gives us some new good flow (yay). Second, it causes some duplication of results that uses 'argv' as a taint source. The duplication isn't very bad, though. And since it is only for argv, I think we can live with it for now.
1 parent dbcd4d6 commit 44e32a6

File tree

13 files changed

+144
-48
lines changed

13 files changed

+144
-48
lines changed

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

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
806806
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
807807
or
808808
// Flow into, through, and out of store nodes
809-
StoreNodeFlow::flowInto(nodeFrom, nodeTo)
809+
StoreNodeFlow::flowInto(nodeFrom.asInstruction(), nodeTo)
810810
or
811811
StoreNodeFlow::flowThrough(nodeFrom, nodeTo)
812812
or
@@ -831,18 +831,11 @@ private predicate adjacentDefUseFlow(Node nodeFrom, Node nodeTo) {
831831
//Def-use flow
832832
Ssa::ssaFlow(nodeFrom, nodeTo)
833833
or
834-
exists(Instruction loadAddress | loadAddress = Ssa::getSourceAddressFromNode(nodeFrom) |
835-
// Use-use flow through reads
836-
exists(Node address |
837-
Ssa::addressFlowTC(address.asInstruction(), loadAddress) and
838-
Ssa::ssaFlow(address, nodeTo)
839-
)
840-
or
841-
// Use-use flow through stores.
842-
exists(Node store |
843-
Ssa::explicitWrite(_, store.asInstruction(), loadAddress) and
844-
Ssa::ssaFlow(store, nodeTo)
845-
)
834+
// Use-use flow through stores.
835+
exists(Instruction loadAddress, Node store |
836+
loadAddress = Ssa::getSourceAddressFromNode(nodeFrom) and
837+
Ssa::explicitWrite(_, store.asInstruction(), loadAddress) and
838+
Ssa::ssaFlow(store, nodeTo)
846839
)
847840
)
848841
}
@@ -906,10 +899,13 @@ private module ReadNodeFlow {
906899
}
907900
}
908901

909-
private module StoreNodeFlow {
902+
/**
903+
* INTERNAL: Do not use.
904+
*/
905+
module StoreNodeFlow {
910906
/** Holds if the store node `nodeTo` should receive flow from `nodeFrom`. */
911-
predicate flowInto(Node nodeFrom, StoreNode nodeTo) {
912-
nodeTo.flowInto(Ssa::getDestinationAddress(nodeFrom.asInstruction()))
907+
predicate flowInto(Instruction instrFrom, StoreNode nodeTo) {
908+
nodeTo.flowInto(Ssa::getDestinationAddress(instrFrom))
913909
}
914910

915911
/** Holds if the store node `nodeTo` should receive flow from `nodeFom`. */

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,64 @@ private module Cached {
494494
explicitWrite(false, storeNode.getStoreInstruction(), def)
495495
)
496496
or
497+
// The destination of a store operation has undergone lvalue-to-rvalue conversion and is now a
498+
// right-hand-side of a store operation.
499+
// Find the next use of the variable in that store operation, and recursively find the load of that
500+
// pointer. For example, consider this case:
501+
//
502+
// ```cpp
503+
// int x = source();
504+
// int* p = &x;
505+
// sink(*p);
506+
// ```
507+
//
508+
// if we want to find the load of the address of `x`, we see that the pointer is stored into `p`,
509+
// and we then need to recursively look for the load of `p`.
510+
exists(
511+
Def def, StoreInstruction store, IRBlock block1, int rnk1, Use use, IRBlock block2, int rnk2
512+
|
513+
store = def.getInstruction() and
514+
store.getSourceValueOperand() = operand and
515+
def.hasRankInBlock(block1, rnk1) and
516+
use.hasRankInBlock(block2, rnk2) and
517+
adjacentDefRead(_, block1, rnk1, block2, rnk2)
518+
|
519+
// The shared SSA library has determined that `use` is the next use of the operand
520+
// so we find the next load of that use (but only if there is no `PostUpdateNode`) we
521+
// need to flow into first.
522+
not StoreNodeFlow::flowInto(store, _) and
523+
flowOutOfAddressStep(use.getOperand(), nodeTo)
524+
or
525+
// It may also be the case that `store` gives rise to another store step. So let's make sure that
526+
// we also take those into account.
527+
StoreNodeFlow::flowInto(store, nodeTo)
528+
)
529+
or
530+
// As we find the next load of an address, we might come across another use of the same variable.
531+
// In that case, we recursively find the next use of _that_ operand, and continue searching for
532+
// the next load of that operand. For example, consider this case:
533+
//
534+
// ```cpp
535+
// int x = source();
536+
// use(&x);
537+
// int* p = &x;
538+
// sink(*p);
539+
// ```
540+
//
541+
// The next use of `x` after its definition is `use(&x)`, but there is a later load of the address
542+
// of `x` that we want to flow to. So we use the shared SSA library to find the next load.
543+
not operand = getSourceAddressOperand(_) and
544+
exists(Use use1, Use use2, IRBlock block1, int rnk1, IRBlock block2, int rnk2 |
545+
use1.getOperand() = operand and
546+
use1.hasRankInBlock(block1, rnk1) and
547+
// Don't flow to the next use if this use is part of a store operation that totally
548+
// overrides a variable.
549+
not explicitWrite(true, _, use1.getOperand().getDef()) and
550+
adjacentDefRead(_, block1, rnk1, block2, rnk2) and
551+
use2.hasRankInBlock(block2, rnk2) and
552+
flowOutOfAddressStep(use2.getOperand(), nodeTo)
553+
)
554+
or
497555
operand = getSourceAddressOperand(nodeTo.asInstruction())
498556
or
499557
exists(ReturnIndirectionInstruction ret |

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/test_diff.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ int main(int argc, char *argv[]) {
9797

9898
char*** p = &argv; // $ ast,ir-path
9999

100-
sink(*p[0]); // $ ast,ir-sink
100+
sink(*p[0]); // $ ast ir-sink=96:26 ir-sink=98:18
101101

102-
calls_sink_with_argv(*p[i]); // $ ir-path MISSING:ast
102+
calls_sink_with_argv(*p[i]); // $ ir-path=96:26 ir-path=98:18 MISSING:ast
103103

104-
sink(*(argv + 1)); // $ ast,ir-path ir-sink
104+
sink(*(argv + 1)); // $ ast ir-path ir-sink
105105

106106
BaseWithPureVirtual* b = new DerivedCallsSink;
107107

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ void test_pointers1()
190190
sink(ptr1); // $ ast MISSING: ir
191191
sink(ptr2); // $ SPURIOUS: ast
192192
sink(*ptr2); // $ ast MISSING: ir
193-
sink(ptr3); // $ ast MISSING: ir
194-
sink(ptr4); // $ SPURIOUS: ast
195-
sink(*ptr4); // $ ast MISSING: ir
193+
sink(ptr3); // $ ast,ir
194+
sink(ptr4); // $ SPURIOUS: ast,ir
195+
sink(*ptr4); // $ ast,ir
196196
}
197197

198198
void test_pointers2()

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,27 @@ void test_lambdas()
1818
sink(a()); // $ ast,ir
1919

2020
auto b = [&] {
21-
sink(t); // $ ast MISSING: ir
21+
sink(t); // $ ast,ir
2222
sink(u);
2323
v = source(); // (v is reference captured)
2424
};
2525
b();
2626
sink(v); // $ MISSING: ast,ir
2727

2828
auto c = [=] {
29-
sink(t); // $ ast MISSING: ir
29+
sink(t); // $ ast,ir
3030
sink(u);
3131
};
3232
c();
3333

3434
auto d = [](int a, int b) {
35-
sink(a); // $ ast MISSING: ir
35+
sink(a); // $ ast,ir
3636
sink(b);
3737
};
3838
d(t, u);
3939

4040
auto e = [](int &a, int &b, int &c) {
41-
sink(a); // $ ast MISSING: ir
41+
sink(a); // $ ast,ir
4242
sink(b);
4343
c = source();
4444
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void local_references(int &source1, int clean1) {
100100
int t = source();
101101
int &ref = t;
102102
t = clean1;
103-
sink(ref); // $ SPURIOUS: ast
103+
sink(ref); // $ SPURIOUS: ast,ir
104104
}
105105

106106
{

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,28 +801,48 @@ edges
801801
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:7:92:7 | i [post update] |
802802
| simple.cpp:94:10:94:11 | a2 [read] [i] | simple.cpp:94:13:94:13 | FieldAddress [read] |
803803
| simple.cpp:94:13:94:13 | FieldAddress [read] | simple.cpp:94:13:94:13 | i |
804+
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | ReturnIndirection [a] |
804805
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | ab [read] [a] |
805806
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [read] [a] |
806807
| struct_init.c:15:8:15:9 | ab [read] [a] | struct_init.c:15:12:15:12 | FieldAddress [read] |
808+
| struct_init.c:15:8:15:9 | ab [read] [a] | struct_init.c:15:12:15:12 | FieldAddress [read] |
809+
| struct_init.c:15:12:15:12 | FieldAddress [read] | struct_init.c:15:12:15:12 | a |
807810
| struct_init.c:15:12:15:12 | FieldAddress [read] | struct_init.c:15:12:15:12 | a |
808811
| struct_init.c:20:13:20:14 | VariableAddress [post update] [a] | struct_init.c:22:8:22:9 | ab [read] [a] |
809812
| struct_init.c:20:13:20:14 | VariableAddress [post update] [a] | struct_init.c:24:10:24:12 | & ... indirection [a] |
813+
| struct_init.c:20:13:20:14 | VariableAddress [post update] [a] | struct_init.c:26:23:29:3 | FieldAddress [post update] [a] |
810814
| struct_init.c:20:17:20:36 | FieldAddress [post update] | struct_init.c:20:13:20:14 | VariableAddress [post update] [a] |
811815
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:17:20:36 | FieldAddress [post update] |
812816
| struct_init.c:22:8:22:9 | ab [read] [a] | struct_init.c:22:11:22:11 | FieldAddress [read] |
813817
| struct_init.c:22:11:22:11 | FieldAddress [read] | struct_init.c:22:11:22:11 | a |
814818
| struct_init.c:24:10:24:12 | & ... indirection [a] | struct_init.c:14:24:14:25 | *ab [a] |
819+
| struct_init.c:24:10:24:12 | & ... indirection [a] | struct_init.c:24:10:24:12 | absink output argument [a] |
820+
| struct_init.c:24:10:24:12 | absink output argument [a] | struct_init.c:26:23:29:3 | FieldAddress [post update] [a] |
815821
| struct_init.c:26:16:26:20 | VariableAddress [post update] [nestedAB, a] | struct_init.c:31:8:31:12 | outer [read] [nestedAB, a] |
816822
| struct_init.c:26:16:26:20 | VariableAddress [post update] [nestedAB, a] | struct_init.c:36:11:36:15 | outer [read] [nestedAB, a] |
823+
| struct_init.c:26:16:26:20 | VariableAddress [post update] [pointerAB, a] | struct_init.c:33:8:33:12 | outer [read] [pointerAB, a] |
817824
| struct_init.c:26:23:29:3 | FieldAddress [post update] [a] | struct_init.c:26:16:26:20 | VariableAddress [post update] [nestedAB, a] |
825+
| struct_init.c:26:23:29:3 | FieldAddress [post update] [a] | struct_init.c:26:16:26:20 | VariableAddress [post update] [pointerAB, a] |
818826
| struct_init.c:27:5:27:23 | FieldAddress [post update] | struct_init.c:26:23:29:3 | FieldAddress [post update] [a] |
819827
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:27:5:27:23 | FieldAddress [post update] |
820828
| struct_init.c:31:8:31:12 | outer [read] [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB [read] [a] |
821829
| struct_init.c:31:14:31:21 | nestedAB [read] [a] | struct_init.c:31:23:31:23 | FieldAddress [read] |
822830
| struct_init.c:31:23:31:23 | FieldAddress [read] | struct_init.c:31:23:31:23 | a |
831+
| struct_init.c:33:8:33:12 | outer [read] [pointerAB, a] | struct_init.c:33:14:33:22 | FieldAddress [read] [a] |
832+
| struct_init.c:33:14:33:22 | FieldAddress [read] [a] | struct_init.c:33:14:33:22 | pointerAB [read] [a] |
833+
| struct_init.c:33:14:33:22 | pointerAB [read] [a] | struct_init.c:33:25:33:25 | FieldAddress [read] |
834+
| struct_init.c:33:25:33:25 | FieldAddress [read] | struct_init.c:33:25:33:25 | a |
823835
| struct_init.c:36:3:36:8 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] |
824836
| struct_init.c:36:11:36:15 | outer [read] [nestedAB, a] | struct_init.c:36:17:36:24 | nestedAB [read] [a] |
825837
| struct_init.c:36:17:36:24 | nestedAB [read] [a] | struct_init.c:36:3:36:8 | & ... [a] |
838+
| struct_init.c:40:13:40:14 | VariableAddress [post update] [a] | struct_init.c:41:23:44:3 | FieldAddress [post update] [a] |
839+
| struct_init.c:40:17:40:36 | FieldAddress [post update] | struct_init.c:40:13:40:14 | VariableAddress [post update] [a] |
840+
| struct_init.c:40:20:40:29 | call to user_input | struct_init.c:40:17:40:36 | FieldAddress [post update] |
841+
| struct_init.c:41:16:41:20 | VariableAddress [post update] [pointerAB, a] | struct_init.c:46:10:46:14 | outer [read] [pointerAB, a] |
842+
| struct_init.c:41:23:44:3 | FieldAddress [post update] [a] | struct_init.c:41:16:41:20 | VariableAddress [post update] [pointerAB, a] |
843+
| struct_init.c:46:3:46:8 | pointerAB [a] | struct_init.c:14:24:14:25 | ab [a] |
844+
| struct_init.c:46:10:46:14 | outer [read] [pointerAB, a] | struct_init.c:46:16:46:24 | FieldAddress [read] [a] |
845+
| struct_init.c:46:16:46:24 | FieldAddress [read] [a] | struct_init.c:46:3:46:8 | pointerAB [a] |
826846
nodes
827847
| A.cpp:23:10:23:10 | c | semmle.label | c |
828848
| A.cpp:25:7:25:10 | this [post update] [c] | semmle.label | this [post update] [c] |
@@ -1650,8 +1670,11 @@ nodes
16501670
| simple.cpp:94:13:94:13 | FieldAddress [read] | semmle.label | FieldAddress [read] |
16511671
| simple.cpp:94:13:94:13 | i | semmle.label | i |
16521672
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
1673+
| struct_init.c:14:24:14:25 | ReturnIndirection [a] | semmle.label | ReturnIndirection [a] |
16531674
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
16541675
| struct_init.c:15:8:15:9 | ab [read] [a] | semmle.label | ab [read] [a] |
1676+
| struct_init.c:15:8:15:9 | ab [read] [a] | semmle.label | ab [read] [a] |
1677+
| struct_init.c:15:12:15:12 | FieldAddress [read] | semmle.label | FieldAddress [read] |
16551678
| struct_init.c:15:12:15:12 | FieldAddress [read] | semmle.label | FieldAddress [read] |
16561679
| struct_init.c:15:12:15:12 | a | semmle.label | a |
16571680
| struct_init.c:20:13:20:14 | VariableAddress [post update] [a] | semmle.label | VariableAddress [post update] [a] |
@@ -1661,17 +1684,33 @@ nodes
16611684
| struct_init.c:22:11:22:11 | FieldAddress [read] | semmle.label | FieldAddress [read] |
16621685
| struct_init.c:22:11:22:11 | a | semmle.label | a |
16631686
| struct_init.c:24:10:24:12 | & ... indirection [a] | semmle.label | & ... indirection [a] |
1687+
| struct_init.c:24:10:24:12 | absink output argument [a] | semmle.label | absink output argument [a] |
16641688
| struct_init.c:26:16:26:20 | VariableAddress [post update] [nestedAB, a] | semmle.label | VariableAddress [post update] [nestedAB, a] |
1689+
| struct_init.c:26:16:26:20 | VariableAddress [post update] [pointerAB, a] | semmle.label | VariableAddress [post update] [pointerAB, a] |
1690+
| struct_init.c:26:23:29:3 | FieldAddress [post update] [a] | semmle.label | FieldAddress [post update] [a] |
16651691
| struct_init.c:26:23:29:3 | FieldAddress [post update] [a] | semmle.label | FieldAddress [post update] [a] |
16661692
| struct_init.c:27:5:27:23 | FieldAddress [post update] | semmle.label | FieldAddress [post update] |
16671693
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
16681694
| struct_init.c:31:8:31:12 | outer [read] [nestedAB, a] | semmle.label | outer [read] [nestedAB, a] |
16691695
| struct_init.c:31:14:31:21 | nestedAB [read] [a] | semmle.label | nestedAB [read] [a] |
16701696
| struct_init.c:31:23:31:23 | FieldAddress [read] | semmle.label | FieldAddress [read] |
16711697
| struct_init.c:31:23:31:23 | a | semmle.label | a |
1698+
| struct_init.c:33:8:33:12 | outer [read] [pointerAB, a] | semmle.label | outer [read] [pointerAB, a] |
1699+
| struct_init.c:33:14:33:22 | FieldAddress [read] [a] | semmle.label | FieldAddress [read] [a] |
1700+
| struct_init.c:33:14:33:22 | pointerAB [read] [a] | semmle.label | pointerAB [read] [a] |
1701+
| struct_init.c:33:25:33:25 | FieldAddress [read] | semmle.label | FieldAddress [read] |
1702+
| struct_init.c:33:25:33:25 | a | semmle.label | a |
16721703
| struct_init.c:36:3:36:8 | & ... [a] | semmle.label | & ... [a] |
16731704
| struct_init.c:36:11:36:15 | outer [read] [nestedAB, a] | semmle.label | outer [read] [nestedAB, a] |
16741705
| struct_init.c:36:17:36:24 | nestedAB [read] [a] | semmle.label | nestedAB [read] [a] |
1706+
| struct_init.c:40:13:40:14 | VariableAddress [post update] [a] | semmle.label | VariableAddress [post update] [a] |
1707+
| struct_init.c:40:17:40:36 | FieldAddress [post update] | semmle.label | FieldAddress [post update] |
1708+
| struct_init.c:40:20:40:29 | call to user_input | semmle.label | call to user_input |
1709+
| struct_init.c:41:16:41:20 | VariableAddress [post update] [pointerAB, a] | semmle.label | VariableAddress [post update] [pointerAB, a] |
1710+
| struct_init.c:41:23:44:3 | FieldAddress [post update] [a] | semmle.label | FieldAddress [post update] [a] |
1711+
| struct_init.c:46:3:46:8 | pointerAB [a] | semmle.label | pointerAB [a] |
1712+
| struct_init.c:46:10:46:14 | outer [read] [pointerAB, a] | semmle.label | outer [read] [pointerAB, a] |
1713+
| struct_init.c:46:16:46:24 | FieldAddress [read] [a] | semmle.label | FieldAddress [read] [a] |
16751714
subpaths
16761715
| A.cpp:31:14:31:21 | c | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:10 | this [post update] [c] | A.cpp:31:14:31:21 | new [post update] [c] |
16771716
| A.cpp:48:12:48:18 | c | A.cpp:29:23:29:23 | c | A.cpp:29:15:29:18 | ReturnValue [c] | A.cpp:48:12:48:18 | call to make [c] |
@@ -1736,6 +1775,7 @@ subpaths
17361775
| simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:21:10:21:13 | *#this [a_] | simple.cpp:21:10:21:13 | ReturnIndirection [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] |
17371776
| simple.cpp:42:7:42:10 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | this [post update] [b_] | simple.cpp:42:7:42:10 | h [post update] [b_] |
17381777
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:78:9:78:15 | this [f2, f1] | simple.cpp:78:9:78:15 | ReturnValue | simple.cpp:84:14:84:20 | call to getf2f1 |
1778+
| struct_init.c:24:10:24:12 | & ... indirection [a] | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | ReturnIndirection [a] | struct_init.c:24:10:24:12 | absink output argument [a] |
17391779
#select
17401780
| A.cpp:49:10:49:13 | (void *)... | A.cpp:47:12:47:18 | new | A.cpp:49:10:49:13 | (void *)... | (void *)... flows from $@ | A.cpp:47:12:47:18 | new | new |
17411781
| A.cpp:56:10:56:17 | (void *)... | A.cpp:55:12:55:19 | (C *)... | A.cpp:56:10:56:17 | (void *)... | (void *)... flows from $@ | A.cpp:55:12:55:19 | (C *)... | (C *)... |
@@ -1842,5 +1882,7 @@ subpaths
18421882
| simple.cpp:94:13:94:13 | i | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:94:13:94:13 | i | i flows from $@ | simple.cpp:92:11:92:20 | call to user_input | call to user_input |
18431883
| struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
18441884
| struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
1885+
| struct_init.c:15:12:15:12 | a | struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:40:20:40:29 | call to user_input | call to user_input |
18451886
| struct_init.c:22:11:22:11 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
18461887
| struct_init.c:31:23:31:23 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
1888+
| struct_init.c:33:25:33:25 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:33:25:33:25 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |

cpp/ql/test/library-tests/dataflow/fields/struct_init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct Outer {
1212
};
1313

1414
void absink(struct AB *ab) {
15-
sink(ab->a); //$ ast,ir=20:20 ast,ir=27:7 ast=40:20 MISSING: ir
15+
sink(ab->a); //$ ast,ir=20:20 ast,ir=27:7 ast,ir=40:20
1616
sink(ab->b); // no flow
1717
}
1818

@@ -30,7 +30,7 @@ int struct_init(void) {
3030

3131
sink(outer.nestedAB.a); //$ ast,ir
3232
sink(outer.nestedAB.b); // no flow
33-
sink(outer.pointerAB->a); //$ ast MISSING: ir
33+
sink(outer.pointerAB->a); //$ ast,ir
3434
sink(outer.pointerAB->b); // no flow
3535

3636
absink(&outer.nestedAB);

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,20 @@ void test_string_constructors_assignments()
119119
void test_range_based_for_loop_string() {
120120
std::string s(source());
121121
for(char c : s) {
122-
sink(c); // $ ast MISSING: ir
122+
sink(c); // $ ast,ir
123123
}
124124

125125
for(std::string::iterator it = s.begin(); it != s.end(); ++it) {
126-
sink(*it); // $ ast MISSING: ir
126+
sink(*it); // $ ast,ir
127127
}
128128

129129
for(char& c : s) {
130-
sink(c); // $ ast MISSING: ir
130+
sink(c); // $ ast,ir
131131
}
132132

133133
const std::string const_s(source());
134134
for(const char& c : const_s) {
135-
sink(c); // $ ast MISSING: ir
135+
sink(c); // $ ast,ir
136136
}
137137
}
138138

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void test_move_assignment_operator()
100100
y = std::move(x);
101101

102102
sink(y.data1); // $ ir ast=95:15 SPURIOUS: ast=93:23
103-
sink(x.data1); // $ ast MISSING: ir
103+
sink(x.data1); // $ ast,ir
104104
}
105105

106106
void test_move_constructor()
@@ -142,7 +142,7 @@ void test_move_assignment_method()
142142
y.move_assign(std::move(x));
143143

144144
sink(y.data1); // $ ir ast=137:15 SPURIOUS: ast=135:23
145-
sink(x.data1); // $ ast MISSING: ir
145+
sink(x.data1); // $ ast,ir
146146
}
147147

148148
}

0 commit comments

Comments
 (0)