@@ -22,6 +22,12 @@ class Bar
2222 Bar () : f(0 , 0 ) {}
2323};
2424
25+ class Outer
26+ {
27+ public:
28+ Bar inner;
29+ };
30+
2531int 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
4855void 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);
0 commit comments