Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 644a0fa

Browse files
committed
C++: Port dataflow/dataflow-tests to inline expectations test library.
1 parent 89a4cff commit 644a0fa

16 files changed

Lines changed: 178 additions & 331 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class Node extends TIRDataFlowNode {
9595
* Gets the uninitialized local variable corresponding to this node, if
9696
* any.
9797
*/
98-
LocalVariable asUninitialized() { none() }
98+
deprecated LocalVariable asUninitialized() { none() }
9999

100100
/**
101101
* Gets an upper bound on the type of this node.

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ void bg_basic(int source) {
66
if (guarded(source)) {
77
sink(source); // no flow
88
} else {
9-
sink(source); // flow
9+
sink(source); // $ ast,ir
1010
}
1111
}
1212

1313
void bg_not(int source) {
1414
if (!guarded(source)) {
15-
sink(source); // flow
15+
sink(source); // $ ast,ir
1616
} else {
1717
sink(source); // no flow
1818
}
@@ -22,15 +22,15 @@ void bg_and(int source, bool arbitrary) {
2222
if (guarded(source) && arbitrary) {
2323
sink(source); // no flow
2424
} else {
25-
sink(source); // flow
25+
sink(source); // $ ast,ir
2626
}
2727
}
2828

2929
void bg_or(int source, bool arbitrary) {
3030
if (guarded(source) || arbitrary) {
31-
sink(source); // flow
31+
sink(source); // $ ast,ir
3232
} else {
33-
sink(source); // flow
33+
sink(source); // $ ast,ir
3434
}
3535
}
3636

@@ -48,21 +48,21 @@ struct XY {
4848
void bg_stackstruct(XY s1, XY s2) {
4949
s1.x = source();
5050
if (guarded(s1.x)) {
51-
sink(s1.x); // no flow [FALSE POSITIVE in AST]
51+
sink(s1.x); // $ SPURIOUS: ast
5252
} else if (guarded(s1.y)) {
53-
sink(s1.x); // flow
53+
sink(s1.x); // $ ast,ir
5454
} else if (guarded(s2.y)) {
55-
sink(s1.x); // flow
55+
sink(s1.x); // $ ast,ir
5656
}
5757
}
5858

5959
void bg_structptr(XY *p1, XY *p2) {
6060
p1->x = source();
6161
if (guarded(p1->x)) {
62-
sink(p1->x); // no flow [FALSE POSITIVE in AST]
62+
sink(p1->x); // $ SPURIOUS: ast
6363
} else if (guarded(p1->y)) {
64-
sink(p1->x); // flow
64+
sink(p1->x); // $ ast,ir
6565
} else if (guarded(p2->x)) {
66-
sink(p1->x); // flow
66+
sink(p1->x); // $ ast,ir
6767
}
6868
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import cpp
22
import semmle.code.cpp.dataflow.DataFlow
3+
import TestUtilities.InlineExpectationsTest
34

45
/**
56
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import cpp
22
import semmle.code.cpp.ir.dataflow.DataFlow
33
import semmle.code.cpp.ir.IR
4+
import TestUtilities.InlineExpectationsTest
45

56
/**
67
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
@@ -24,9 +25,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
2425
source.asExpr().(FunctionCall).getTarget().getName() = "source"
2526
or
2627
source.asParameter().getName().matches("source%")
27-
or
28-
// Track uninitialized variables
29-
exists(source.asUninitialized())
3028
}
3129

3230
override predicate isSink(DataFlow::Node sink) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void sink(int);
99
// this result and be forced to write a better test if the function signature
1010
// detection should improve.
1111
void calleeAcrossLinkTargets(long x) {
12-
sink(x);
12+
sink(x); // $ ast,ir
1313
}
1414

1515
void calleeAcrossLinkTargets(int x); // no body

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,38 @@ void following_pointers(
1515
twoIntFields *sourceStruct1_ptr,
1616
int (*sourceFunctionPointer)())
1717
{
18-
sink(sourceArray1); // flow
18+
sink(sourceArray1); // $ ast,ir
1919

2020
sink(sourceArray1[0]); // no flow
2121
sink(*sourceArray1); // no flow
22-
sink(&sourceArray1); // flow (should probably be taint only)
22+
sink(&sourceArray1); // $ ast // [should probably taint only]
2323

2424
sink(sourceStruct1.m1); // no flow
2525
sink(sourceStruct1_ptr->m1); // no flow
2626
sink(sourceStruct1_ptr->getFirst()); // no flow
2727

2828
sourceStruct1_ptr->m1 = source();
29-
sink(sourceStruct1_ptr->m1); // flow
30-
sink(sourceStruct1_ptr->getFirst()); // flow
29+
sink(sourceStruct1_ptr->m1); // $ ast,ir
30+
sink(sourceStruct1_ptr->getFirst()); // $ ast,ir
3131
sink(sourceStruct1_ptr->m2); // no flow
3232
sink(sourceStruct1.m1); // no flow
3333

3434
twoIntFields s = { source(), source() };
3535

3636

37-
sink(s.m2); // flow
37+
sink(s.m2); // $ ast,ir
3838

3939
twoIntFields sArray[1] = { { source(), source() } };
4040
// TODO: fix this like above
41-
sink(sArray[0].m2); // flow (AST dataflow misses this due to limitations of the analysis)
41+
sink(sArray[0].m2); // $ ir MISSING: ast
4242

4343
twoIntFields sSwapped = { .m2 = source(), .m1 = 0 };
4444

45-
sink(sSwapped.m2); // flow
45+
sink(sSwapped.m2); // $ ast,ir
4646

4747
sink(sourceFunctionPointer()); // no flow
4848

4949
int stackArray[2] = { source(), source() };
5050
stackArray[0] = source();
51-
sink(stackArray); // flow
51+
sink(stackArray); // $ ast MISSING: ir
5252
}
53-

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

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct Top {
88
virtual void isSink(int x) { }
99
virtual int notSource1() { return source(); }
1010
virtual int notSource2() { return source(); }
11-
virtual void notSink(int x) { sink(x); }
11+
virtual void notSink(int x) { sink(x); } // $ SPURIOUS: ast,ir=37:19 ast,ir=45:18
1212
};
1313

1414
// This class has the correct behavior for just the functions ending in 2.
@@ -20,29 +20,29 @@ struct Middle : Top {
2020
// This class has all the behavior suggested by the function names.
2121
struct Bottom : Middle {
2222
int isSource1() override { return source(); }
23-
void isSink(int x) override { sink(x); }
23+
void isSink(int x) override { sink(x); } // $ ir=33:18 ir=41:17 ir=69:15 ir=73:14 ir=81:13 MISSING: ast=33:18 ast=41:17 ast=69:15 ast=73:14 ast=81:13
2424
int notSource1() override { return 0; }
2525
void notSink(int x) override { }
2626
};
2727

2828
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) {
2929
Top *topPtr = bottomPtr, &topRef = bottomRef;
3030

31-
sink(topPtr->isSource1()); // flow [NOT DETECTED by AST]
32-
sink(topPtr->isSource2()); // flow [NOT DETECTED by AST]
33-
topPtr->isSink(source()); // flow [NOT DETECTED by AST]
31+
sink(topPtr->isSource1()); // $ ir MISSING: ast
32+
sink(topPtr->isSource2()); // $ ir MISSING: ast
33+
topPtr->isSink(source()); // causing a MISSING for ast
3434

35-
sink(topPtr->notSource1()); // no flow [FALSE POSITIVE]
36-
sink(topPtr->notSource2()); // no flow [FALSE POSITIVE]
37-
topPtr->notSink(source()); // no flow [FALSE POSITIVE]
35+
sink(topPtr->notSource1()); // $ SPURIOUS: ast,ir
36+
sink(topPtr->notSource2()); // $ SPURIOUS: ast,ir
37+
topPtr->notSink(source()); // causing SPURIOUS for ast,ir
3838

39-
sink(topRef.isSource1()); // flow [NOT DETECTED by AST]
40-
sink(topRef.isSource2()); // flow [NOT DETECTED by AST]
41-
topRef.isSink(source()); // flow [NOT DETECTED by AST]
39+
sink(topRef.isSource1()); // $ ir MISSING: ast
40+
sink(topRef.isSource2()); // $ ir MISSING: ast
41+
topRef.isSink(source()); // causing a MISSING for ast
4242

43-
sink(topRef.notSource1()); // no flow [FALSE POSITIVE]
44-
sink(topRef.notSource2()); // no flow [FALSE POSITIVE]
45-
topRef.notSink(source()); // no flow [FALSE POSITIVE]
43+
sink(topRef.notSource1()); // $ SPURIOUS: ast,ir
44+
sink(topRef.notSource2()); // $ SPURIOUS: ast,ir
45+
topRef.notSink(source()); // causing SPURIOUS for ast,ir
4646
}
4747

4848
Top *globalBottom, *globalMiddle;
@@ -52,10 +52,10 @@ Top *readGlobalBottom() {
5252
}
5353

5454
void DispatchThroughGlobal() {
55-
sink(globalBottom->isSource1()); // flow [NOT DETECTED by AST]
55+
sink(globalBottom->isSource1()); // $ ir MISSING: ast
5656
sink(globalMiddle->isSource1()); // no flow
5757

58-
sink(readGlobalBottom()->isSource1()); // flow [NOT DETECTED by AST]
58+
sink(readGlobalBottom()->isSource1()); // $ ir MISSING: ast
5959

6060
globalBottom = new Bottom();
6161
globalMiddle = new Middle();
@@ -66,34 +66,34 @@ Top *allocateBottom() {
6666
}
6767

6868
void callSinkByPointer(Top *top) {
69-
top->isSink(source()); // flow [NOT DETECTED by AST]
69+
top->isSink(source()); // leads to MISSING from ast
7070
}
7171

7272
void callSinkByReference(Top &top) {
73-
top.isSink(source()); // flow [NOT DETECTED by AST]
73+
top.isSink(source()); // leads to MISSING from ast
7474
}
7575

7676
void globalVirtualDispatch() {
7777
callSinkByPointer(allocateBottom());
7878
callSinkByReference(*allocateBottom());
7979

8080
Top *x = allocateBottom();
81-
x->isSink(source()); // flow [NOT DETECTED by AST]
81+
x->isSink(source()); // $ MISSING: ast,ir
8282
}
8383

8484
Top *identity(Top *top) {
8585
return top;
8686
}
8787

8888
void callIdentityFunctions(Top *top, Bottom *bottom) {
89-
identity(bottom)->isSink(source()); // flow [NOT DETECTED]
89+
identity(bottom)->isSink(source()); // $ MISSING: ast,ir
9090
identity(top)->isSink(source()); // now flow
9191
}
9292

9393
using SinkFunctionType = void (*)(int);
9494

9595
void callSink(int x) {
96-
sink(x);
96+
sink(x); // $ ir=107:17 ir=140:8 ir=144:8 MISSING: ast=107:17 ast=140:8 ast=144:8
9797
}
9898

9999
SinkFunctionType returnCallSink() {
@@ -104,7 +104,7 @@ void testFunctionPointer(SinkFunctionType maybeCallSink, SinkFunctionType dontCa
104104
if (b) {
105105
maybeCallSink = returnCallSink();
106106
}
107-
maybeCallSink(source()); // flow [NOT DETECTED by AST]
107+
maybeCallSink(source());
108108
dontCallSink(source()); // no flow
109109
}
110110

@@ -126,8 +126,8 @@ namespace virtual_inheritance {
126126
// get flow from a `Middle` value to the call qualifier.
127127
Top *topPtr = bottomPtr, &topRef = bottomRef;
128128

129-
sink(topPtr->isSource()); // flow [NOT DETECTED]
130-
sink(topRef.isSource()); // flow [NOT DETECTED]
129+
sink(topPtr->isSource()); // $ MISSING: ast,ir
130+
sink(topRef.isSource()); // $ MISSING: ast,ir
131131
}
132132
}
133133

@@ -170,6 +170,6 @@ void set_global_union_field_u_f() {
170170

171171
void test_call_sink_through_union_2() {
172172
set_global_union_field_u_f();
173-
call_sink_through_union_field_u_f(u2.u.f); // flow [NOT DETECTED]
174-
call_sink_through_union_field_u_g(u2.u.g); // flow [NOT DETECTED]
173+
call_sink_through_union_field_u_f(u2.u.f); // $ MISSING: ast,ir
174+
call_sink_through_union_field_u_g(u2.u.g); // $ MISSING: ast,ir
175175
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ void sink(int);
33

44
void throughLocal() {
55
int local = source();
6-
sink(local); // flow
6+
sink(local); // $ ast,ir
77
}
88

99
int flowTestGlobal1 = 0;
1010

1111
void readWriteGlobal1() {
12-
sink(flowTestGlobal1); // flow
12+
sink(flowTestGlobal1); // $ ir MISSING: ast
1313
flowTestGlobal1 = source();
1414
}
1515

1616
static int flowTestGlobal2 = 0;
1717

1818
void readGlobal2() {
19-
sink(flowTestGlobal2); // flow
19+
sink(flowTestGlobal2); // $ ir MISSING: ast
2020
}
2121

2222
void writeGlobal2() {

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,37 @@ void test_lambdas()
1111
int w = 0;
1212

1313
auto a = [t, u]() -> int {
14-
sink(t); // flow from source()
14+
sink(t); // $ ast,ir
1515
sink(u);
1616
return t;
1717
};
18-
sink(a()); // flow from source()
18+
sink(a()); // $ ast,ir
1919

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

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

3434
auto d = [](int a, int b) {
35-
sink(a); // flow from source()
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); // flow from source()
41+
sink(a); // $ ast,ir
4242
sink(b);
4343
c = source();
4444
};
4545
e(t, u, w);
46-
sink(w); // flow from source()
46+
sink(w); // $ ast,ir
4747
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ namespace withoutFields {
5353
int x1, x2, x3, x4;
5454

5555
assignWrapper(x1, source());
56-
sink(x1); // flow [FALSE POSITIVE from uninitialized]
56+
sink(x1); // $ ast=55:23 ir SPURIOUS: ast=53:9
5757

5858
notAssign(x2, source());
59-
sink(x2); // no flow [FALSE POSITIVE from uninitialized, FALSE POSITIVE by IR]
59+
sink(x2); // $ SPURIOUS: ast,ir
6060

6161
sourceToParamWrapper(x3);
62-
sink(x3); // flow [FALSE POSITIVE from uninitialized]
62+
sink(x3); // $ ast=29:11 ir SPURIOUS: ast=53:17
6363

6464
notSource(x4);
65-
sink(x4); // no flow [FALSE POSITIVE from uninitialized, FALSE POSITIVE by IR]
65+
sink(x4); // $ SPURIOUS: ast,ir
6666
}
6767
}
6868

@@ -120,15 +120,15 @@ namespace withFields {
120120
Int x1, x2, x3, x4;
121121

122122
assignWrapper(x1, source());
123-
sink(x1.val); // flow
123+
sink(x1.val); // $ ast,ir
124124

125125
notAssign(x2, source());
126-
sink(x2.val); // no flow [FALSE POSITIVE]
126+
sink(x2.val); // $ SPURIOUS: ast,ir
127127

128128
sourceToParamWrapper(x3);
129-
sink(x3.val); // flow
129+
sink(x3.val); // $ ast,ir
130130

131131
notSource(x4);
132-
sink(x4.val); // no flow [FALSE POSITIVE]
132+
sink(x4.val); // $ SPURIOUS: ast,ir
133133
}
134134
}

0 commit comments

Comments
 (0)