Skip to content

Commit f414b27

Browse files
committed
C++: Modify complex.cpp test to account for longer access paths in the dataflow library
1 parent f5f3405 commit f414b27

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

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

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ class Bar
2222
Bar() : f(0, 0) {}
2323
};
2424

25+
class Outer
26+
{
27+
public:
28+
Bar inner;
29+
};
30+
2531
int user_input()
2632
{
2733
return 42;
@@ -31,31 +37,32 @@ void sink(int x)
3137
{
3238
}
3339

34-
void bar(Bar &b)
40+
void bar(Outer &b)
3541
{
3642
// The library correctly finds that the four `user_input` sources can make it
3743
// to the `sink` calls, but it also finds some source/sink combinations that
3844
// are impossible. Those false positives here are a consequence of how the
3945
// shared data flow library overapproximates field flow. The library only
40-
// tracks the head (`f`) and the length (2) of the field access path, and
41-
// then it tracks that both `a_` and `b_` have followed `f` in _some_ access
42-
// path somewhere in the search. That makes the library conclude that there
43-
// could be flow to `b.f.a_` even when the flow was actually to `b.f.b_`.
44-
sink(b.f.a()); //$ast=flow 55:13 $ast=flow 57:13 $f-:ir=flow
45-
sink(b.f.b()); //$ast=flow 56:13 $ast=flow 58:13 $f-:ir=flow
46+
// tracks the final two fields (`f` and `inner`) and the length (3) of the field
47+
// access path, and then it tracks that both `a_` and `b_` have followed `f.inner`
48+
// in _some_ access path somewhere in the search. That makes the library conclude
49+
// that there could be flow to `b.inner.f.a_` even when the flow was actually to
50+
// `b.inner.f.b_`.
51+
sink(b.inner.f.a()); // $ast=flow 61:19 $f+:ast=flow 62:19 $ast=flow 63:19 $f+:ast=flow 64:19 $f-:ir=flow
52+
sink(b.inner.f.b()); // $f+:ast=flow 61:19 $ast=flow 62:19 $f+:ast=flow 63:19 $ast=flow 64:19 $f-:ir=flow
4653
}
4754

4855
void foo()
4956
{
50-
Bar b1;
51-
Bar b2;
52-
Bar b3;
53-
Bar b4;
57+
Outer b1;
58+
Outer b2;
59+
Outer b3;
60+
Outer b4;
5461

55-
b1.f.setA(user_input());
56-
b2.f.setB(user_input());
57-
b3.f.setA(user_input());
58-
b3.f.setB(user_input());
62+
b1.inner.f.setA(user_input());
63+
b2.inner.f.setB(user_input());
64+
b3.inner.f.setA(user_input());
65+
b3.inner.f.setB(user_input());
5966

6067
// Only a() should alert
6168
bar(b1);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ uniqueEnclosingCallable
44
uniqueTypeBound
55
| complex.cpp:22:11:22:17 | constructor init of field f [post-this] | Node should have one type bound but has 0. |
66
| complex.cpp:22:11:22:17 | constructor init of field f [pre-this] | Node should have one type bound but has 0. |
7+
| complex.cpp:25:7:25:7 | constructor init of field inner [post-this] | Node should have one type bound but has 0. |
8+
| complex.cpp:25:7:25:7 | constructor init of field inner [pre-this] | Node should have one type bound but has 0. |
79
uniqueTypeRepr
810
| complex.cpp:22:11:22:17 | constructor init of field f [post-this] | Node should have one type representation but has 0. |
911
| complex.cpp:22:11:22:17 | constructor init of field f [pre-this] | Node should have one type representation but has 0. |
12+
| complex.cpp:25:7:25:7 | constructor init of field inner [post-this] | Node should have one type representation but has 0. |
13+
| complex.cpp:25:7:25:7 | constructor init of field inner [pre-this] | Node should have one type representation but has 0. |
1014
uniqueNodeLocation
1115
| A.cpp:38:7:38:8 | call to C | Node should have one location but has 2. |
1216
| A.cpp:39:7:39:8 | call to C | Node should have one location but has 2. |

0 commit comments

Comments
 (0)