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

Skip to content

Commit 6d4d131

Browse files
pavgustjbj
authored andcommitted
C++ field flow: Add test.
This is a fairly direct translation of the Java field flow test to C++. Not all the `// flow` annotations are currently accurate.
1 parent dccc0f4 commit 6d4d131

5 files changed

Lines changed: 417 additions & 0 deletions

File tree

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
class A
2+
{
3+
4+
class C
5+
{
6+
public:
7+
virtual void f(void *) {}
8+
};
9+
class C1 : public C
10+
{
11+
public:
12+
A *a;
13+
};
14+
class C2 : public C
15+
{
16+
};
17+
18+
class B
19+
{
20+
public:
21+
C *c;
22+
B() {}
23+
B(C *c)
24+
{
25+
this->c = c;
26+
}
27+
void set(C *c) { this->c = c; }
28+
C *get() { return this->c; }
29+
static B *make(C *c)
30+
{
31+
return new B(c);
32+
}
33+
};
34+
35+
public:
36+
void f0()
37+
{
38+
C cc;
39+
C ct;
40+
cc.f(nullptr);
41+
ct.f(new C());
42+
sink(&cc); // no flow
43+
sink(&ct); // flow
44+
}
45+
void f1()
46+
{
47+
C *c = new C();
48+
B *b = B::make(c);
49+
sink(b->c); // flow
50+
}
51+
52+
void f2()
53+
{
54+
B *b = new B();
55+
b->set(new C1());
56+
sink(b->get()); // flow
57+
sink((new B(new C()))->get()); // flow
58+
}
59+
60+
void f3()
61+
{
62+
B *b1 = new B();
63+
B *b2;
64+
b2 = setOnB(b1, new C2());
65+
sink(b1->c); // no flow
66+
sink(b2->c); // flow
67+
}
68+
69+
void f4()
70+
{
71+
B *b1 = new B();
72+
B *b2;
73+
b2 = setOnBWrap(b1, new C2());
74+
sink(b1->c); // no flow
75+
sink(b2->c); // flow
76+
}
77+
78+
B *setOnBWrap(B *b1, C *c)
79+
{
80+
B *b2;
81+
b2 = setOnB(b1, c);
82+
return r() ? b1 : b2;
83+
}
84+
85+
A::B *setOnB(B *b1, C *c)
86+
{
87+
if (r())
88+
{
89+
B *b2 = new B();
90+
b2->set(c);
91+
return b2;
92+
}
93+
return b1;
94+
}
95+
96+
void f5()
97+
{
98+
A *a = new A();
99+
C1 *c1 = new C1();
100+
c1->a = a;
101+
f6(c1);
102+
}
103+
void f6(C *c)
104+
{
105+
if (C1 *c1 = dynamic_cast<C1 *>(c))
106+
{
107+
sink(c1->a); // flow
108+
}
109+
C *cc;
110+
if (C2 *c2 = dynamic_cast<C2 *>(c))
111+
{
112+
cc = c2;
113+
}
114+
else
115+
{
116+
cc = new C1();
117+
}
118+
if (C1 *c1 = dynamic_cast<C1 *>(cc))
119+
{
120+
sink(c1->a); // no flow, stopped by cast to C2
121+
}
122+
}
123+
124+
void f7(B *b)
125+
{
126+
b->set(new C());
127+
}
128+
void f8()
129+
{
130+
B *b = new B();
131+
f7(b);
132+
sink(b->c); // flow
133+
}
134+
135+
class D
136+
{
137+
public:
138+
A::B *b;
139+
140+
D(A::B *b, bool x)
141+
{
142+
b->c = new C();
143+
this->b = x ? b : new B();
144+
}
145+
};
146+
147+
void
148+
f9()
149+
{
150+
B *b = new B();
151+
D *d = new D(b, r());
152+
sink(d->b); // flow x2
153+
sink(d->b->c); // flow
154+
sink(b->c); // flow
155+
}
156+
157+
void f10()
158+
{
159+
B *b = new B();
160+
MyList *l1 = new MyList(b, new MyList(nullptr, nullptr));
161+
MyList *l2 = new MyList(nullptr, l1);
162+
MyList *l3 = new MyList(nullptr, l2);
163+
sink(l3->head); // no flow, b is nested beneath at least one ->next
164+
sink(l3->next->head); // flow, the precise nesting depth isn't tracked
165+
sink(l3->next->next->head); // flow
166+
sink(l3->next->next->next->head); // flow
167+
for (MyList *l = l3; l != nullptr; l = l->next)
168+
{
169+
sink(l->head); // flow
170+
}
171+
}
172+
173+
static void sink(void *o) {}
174+
bool r() { return reinterpret_cast<long long>(this) % 10 > 5; }
175+
176+
class MyList
177+
{
178+
public:
179+
B *head;
180+
MyList *next;
181+
MyList(B *newHead, MyList *next)
182+
{
183+
head = newHead;
184+
this->next = next;
185+
}
186+
};
187+
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
class B
2+
{
3+
4+
void f1()
5+
{
6+
Elem *e = new Elem();
7+
Box1 *b1 = new Box1(e, nullptr);
8+
Box2 *b2 = new Box2(b1);
9+
sink(b2->box1->elem1); // flow
10+
sink(b2->box1->elem2); // FP due to flow in f2 below
11+
}
12+
13+
void f2()
14+
{
15+
Elem *e = new B::Elem();
16+
Box1 *b1 = new B::Box1(nullptr, e);
17+
Box2 *b2 = new Box2(b1);
18+
sink(b2->box1->elem1); // FP due to flow in f1 above
19+
sink(b2->box1->elem2); // flow
20+
}
21+
22+
static void sink(void *o) {}
23+
24+
class Elem
25+
{
26+
};
27+
28+
class Box1
29+
{
30+
public:
31+
Elem *elem1;
32+
Elem *elem2;
33+
Box1(Elem *e1, Elem *e2)
34+
{
35+
this->elem1 = e1;
36+
this->elem2 = e2;
37+
}
38+
};
39+
40+
class Box2
41+
{
42+
public:
43+
Box1 *box1;
44+
Box2(Box1 *b1)
45+
{
46+
this->box1 = b1;
47+
}
48+
};
49+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
class C
3+
{
4+
class Elem
5+
{
6+
};
7+
8+
private:
9+
Elem *s1 = new Elem();
10+
const Elem *s2 = new Elem();
11+
Elem *s3;
12+
13+
public:
14+
const static Elem *s4;
15+
16+
void main(void)
17+
{
18+
C *c = new C();
19+
c->func();
20+
}
21+
22+
C() : s1(new Elem())
23+
{
24+
this->s3 = new Elem();
25+
}
26+
27+
void func()
28+
{
29+
sink(s1);
30+
sink(s2);
31+
sink(s3);
32+
sink(s4);
33+
}
34+
35+
static void sink(const void *o) {}
36+
};
37+
const C::Elem *C::s4 = new Elem();
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
edges
2+
| A.cpp:41:10:41:16 | new [void] | A.cpp:43:10:43:12 | & ... |
3+
| A.cpp:47:12:47:18 | new [void] | A.cpp:48:20:48:20 | c [void] |
4+
| A.cpp:48:12:48:18 | call to make [c, ... (1)] | A.cpp:49:10:49:10 | b [c, ... (1)] |
5+
| A.cpp:48:20:48:20 | c [void] | A.cpp:48:12:48:18 | call to make [c, ... (1)] |
6+
| A.cpp:49:10:49:10 | b [c, ... (1)] | A.cpp:49:13:49:13 | c |
7+
| A.cpp:55:5:55:5 | b [post update] [c, ... (1)] | A.cpp:56:10:56:10 | b [c, ... (1)] |
8+
| A.cpp:55:12:55:19 | new [void] | A.cpp:55:5:55:5 | b [post update] [c, ... (1)] |
9+
| A.cpp:56:10:56:10 | b [c, ... (1)] | A.cpp:56:13:56:15 | call to get |
10+
| A.cpp:57:11:57:24 | call to B [post update] [c, ... (1)] | A.cpp:57:11:57:24 | new [c, ... (1)] |
11+
| A.cpp:57:11:57:24 | new [c, ... (1)] | A.cpp:57:28:57:30 | call to get |
12+
| A.cpp:57:17:57:23 | new [void] | A.cpp:57:11:57:24 | call to B [post update] [c, ... (1)] |
13+
| A.cpp:64:10:64:15 | call to setOnB [c, ... (1)] | A.cpp:66:10:66:11 | b2 [c, ... (1)] |
14+
| A.cpp:64:21:64:28 | new [void] | A.cpp:64:10:64:15 | call to setOnB [c, ... (1)] |
15+
| A.cpp:66:10:66:11 | b2 [c, ... (1)] | A.cpp:66:14:66:14 | c |
16+
| A.cpp:73:10:73:19 | call to setOnBWrap [c, ... (1)] | A.cpp:75:10:75:11 | b2 [c, ... (1)] |
17+
| A.cpp:73:25:73:32 | new [void] | A.cpp:73:10:73:19 | call to setOnBWrap [c, ... (1)] |
18+
| A.cpp:75:10:75:11 | b2 [c, ... (1)] | A.cpp:75:14:75:14 | c |
19+
| A.cpp:98:12:98:18 | new [void] | A.cpp:100:5:100:13 | ... = ... [void] |
20+
| A.cpp:100:5:100:6 | c1 [post update] [a, ... (1)] | A.cpp:101:8:101:9 | c1 [a, ... (1)] |
21+
| A.cpp:100:5:100:13 | ... = ... [void] | A.cpp:100:5:100:6 | c1 [post update] [a, ... (1)] |
22+
| A.cpp:101:8:101:9 | c1 [a, ... (1)] | A.cpp:103:14:103:14 | c [a, ... (1)] |
23+
| A.cpp:103:14:103:14 | c [a, ... (1)] | A.cpp:107:12:107:13 | c1 [a, ... (1)] |
24+
| A.cpp:103:14:103:14 | c [a, ... (1)] | A.cpp:120:12:120:13 | c1 [a, ... (1)] |
25+
| A.cpp:107:12:107:13 | c1 [a, ... (1)] | A.cpp:107:16:107:16 | a |
26+
| A.cpp:120:12:120:13 | c1 [a, ... (1)] | A.cpp:120:16:120:16 | a |
27+
| A.cpp:126:5:126:5 | b [post update] [c, ... (1)] | A.cpp:131:8:131:8 | b [post update] [c, ... (1)] |
28+
| A.cpp:126:12:126:18 | new [void] | A.cpp:126:5:126:5 | b [post update] [c, ... (1)] |
29+
| A.cpp:131:8:131:8 | b [post update] [c, ... (1)] | A.cpp:132:10:132:10 | b [c, ... (1)] |
30+
| A.cpp:132:10:132:10 | b [c, ... (1)] | A.cpp:132:13:132:13 | c |
31+
| A.cpp:142:7:142:7 | b [post update] [c, ... (1)] | A.cpp:143:7:143:31 | ... = ... [c, ... (1)] |
32+
| A.cpp:142:7:142:7 | b [post update] [c, ... (1)] | A.cpp:151:18:151:18 | b [post update] [c, ... (1)] |
33+
| A.cpp:142:7:142:20 | ... = ... [void] | A.cpp:142:7:142:7 | b [post update] [c, ... (1)] |
34+
| A.cpp:142:14:142:20 | new [void] | A.cpp:142:7:142:20 | ... = ... [void] |
35+
| A.cpp:143:7:143:10 | this [post update] [b, ... (1)] | A.cpp:151:12:151:24 | call to D [post update] [b, ... (1)] |
36+
| A.cpp:143:7:143:10 | this [post update] [b, ... (2)] | A.cpp:151:12:151:24 | call to D [post update] [b, ... (2)] |
37+
| A.cpp:143:7:143:31 | ... = ... [c, ... (1)] | A.cpp:143:7:143:10 | this [post update] [b, ... (2)] |
38+
| A.cpp:143:7:143:31 | ... = ... [void] | A.cpp:143:7:143:10 | this [post update] [b, ... (1)] |
39+
| A.cpp:143:25:143:31 | new [void] | A.cpp:143:7:143:31 | ... = ... [void] |
40+
| A.cpp:150:12:150:18 | new [void] | A.cpp:151:18:151:18 | b [void] |
41+
| A.cpp:151:12:151:24 | call to D [post update] [b, ... (1)] | A.cpp:152:10:152:10 | d [b, ... (1)] |
42+
| A.cpp:151:12:151:24 | call to D [post update] [b, ... (2)] | A.cpp:153:10:153:10 | d [b, ... (2)] |
43+
| A.cpp:151:18:151:18 | b [post update] [c, ... (1)] | A.cpp:154:10:154:10 | b [c, ... (1)] |
44+
| A.cpp:151:18:151:18 | b [void] | A.cpp:151:12:151:24 | call to D [post update] [b, ... (1)] |
45+
| A.cpp:152:10:152:10 | d [b, ... (1)] | A.cpp:152:13:152:13 | b |
46+
| A.cpp:153:10:153:10 | d [b, ... (2)] | A.cpp:153:13:153:13 | b [c, ... (1)] |
47+
| A.cpp:153:13:153:13 | b [c, ... (1)] | A.cpp:153:16:153:16 | c |
48+
| A.cpp:154:10:154:10 | b [c, ... (1)] | A.cpp:154:13:154:13 | c |
49+
| A.cpp:159:12:159:18 | new [void] | A.cpp:160:29:160:29 | b [void] |
50+
| A.cpp:160:18:160:60 | call to MyList [post update] [head, ... (1)] | A.cpp:161:38:161:39 | l1 [head, ... (1)] |
51+
| A.cpp:160:29:160:29 | b [void] | A.cpp:160:18:160:60 | call to MyList [post update] [head, ... (1)] |
52+
| A.cpp:161:18:161:40 | call to MyList [post update] [next, ... (2)] | A.cpp:162:38:162:39 | l2 [next, ... (2)] |
53+
| A.cpp:161:38:161:39 | l1 [head, ... (1)] | A.cpp:161:18:161:40 | call to MyList [post update] [next, ... (2)] |
54+
| A.cpp:162:18:162:40 | call to MyList [post update] [next, ... (3)] | A.cpp:165:10:165:11 | l3 [next, ... (3)] |
55+
| A.cpp:162:18:162:40 | call to MyList [post update] [next, ... (3)] | A.cpp:167:44:167:44 | l [next, ... (3)] |
56+
| A.cpp:162:38:162:39 | l2 [next, ... (2)] | A.cpp:162:18:162:40 | call to MyList [post update] [next, ... (3)] |
57+
| A.cpp:165:10:165:11 | l3 [next, ... (3)] | A.cpp:165:14:165:17 | next [next, ... (2)] |
58+
| A.cpp:165:14:165:17 | next [next, ... (2)] | A.cpp:165:20:165:23 | next [head, ... (1)] |
59+
| A.cpp:165:20:165:23 | next [head, ... (1)] | A.cpp:165:26:165:29 | head |
60+
| A.cpp:167:44:167:44 | l [next, ... (2)] | A.cpp:167:47:167:50 | next [head, ... (1)] |
61+
| A.cpp:167:44:167:44 | l [next, ... (3)] | A.cpp:167:47:167:50 | next [next, ... (2)] |
62+
| A.cpp:167:47:167:50 | next [head, ... (1)] | A.cpp:169:12:169:12 | l [head, ... (1)] |
63+
| A.cpp:167:47:167:50 | next [next, ... (2)] | A.cpp:167:44:167:44 | l [next, ... (2)] |
64+
| A.cpp:169:12:169:12 | l [head, ... (1)] | A.cpp:169:15:169:18 | head |
65+
| B.cpp:6:15:6:24 | new [void] | B.cpp:7:25:7:25 | e [void] |
66+
| B.cpp:7:16:7:35 | call to Box1 [post update] [elem1, ... (1)] | B.cpp:8:25:8:26 | b1 [elem1, ... (1)] |
67+
| B.cpp:7:25:7:25 | e [void] | B.cpp:7:16:7:35 | call to Box1 [post update] [elem1, ... (1)] |
68+
| B.cpp:8:16:8:27 | call to Box2 [post update] [box1, ... (2)] | B.cpp:9:10:9:11 | b2 [box1, ... (2)] |
69+
| B.cpp:8:16:8:27 | call to Box2 [post update] [box1, ... (2)] | B.cpp:10:10:10:11 | b2 [box1, ... (2)] |
70+
| B.cpp:8:25:8:26 | b1 [elem1, ... (1)] | B.cpp:8:16:8:27 | call to Box2 [post update] [box1, ... (2)] |
71+
| B.cpp:9:10:9:11 | b2 [box1, ... (2)] | B.cpp:9:14:9:17 | box1 [elem1, ... (1)] |
72+
| B.cpp:9:14:9:17 | box1 [elem1, ... (1)] | B.cpp:9:20:9:24 | elem1 |
73+
| B.cpp:10:10:10:11 | b2 [box1, ... (2)] | B.cpp:10:14:10:17 | box1 [elem2, ... (1)] |
74+
| B.cpp:10:14:10:17 | box1 [elem2, ... (1)] | B.cpp:10:20:10:24 | elem2 |
75+
| B.cpp:15:15:15:27 | new [void] | B.cpp:16:37:16:37 | e [void] |
76+
| B.cpp:16:16:16:38 | call to Box1 [post update] [elem2, ... (1)] | B.cpp:17:25:17:26 | b1 [elem2, ... (1)] |
77+
| B.cpp:16:37:16:37 | e [void] | B.cpp:16:16:16:38 | call to Box1 [post update] [elem2, ... (1)] |
78+
| B.cpp:17:16:17:27 | call to Box2 [post update] [box1, ... (2)] | B.cpp:18:10:18:11 | b2 [box1, ... (2)] |
79+
| B.cpp:17:16:17:27 | call to Box2 [post update] [box1, ... (2)] | B.cpp:19:10:19:11 | b2 [box1, ... (2)] |
80+
| B.cpp:17:25:17:26 | b1 [elem2, ... (1)] | B.cpp:17:16:17:27 | call to Box2 [post update] [box1, ... (2)] |
81+
| B.cpp:18:10:18:11 | b2 [box1, ... (2)] | B.cpp:18:14:18:17 | box1 [elem1, ... (1)] |
82+
| B.cpp:18:14:18:17 | box1 [elem1, ... (1)] | B.cpp:18:20:18:24 | elem1 |
83+
| B.cpp:19:10:19:11 | b2 [box1, ... (2)] | B.cpp:19:14:19:17 | box1 [elem2, ... (1)] |
84+
| B.cpp:19:14:19:17 | box1 [elem2, ... (1)] | B.cpp:19:20:19:24 | elem2 |
85+
| C.cpp:18:12:18:18 | call to C [post update] [s3, ... (1)] | C.cpp:19:5:19:5 | c [s3, ... (1)] |
86+
| C.cpp:19:5:19:5 | c [s3, ... (1)] | C.cpp:27:8:27:11 | `this` parameter in func [s3, ... (1)] |
87+
| C.cpp:24:5:24:8 | this [post update] [s3, ... (1)] | C.cpp:18:12:18:18 | call to C [post update] [s3, ... (1)] |
88+
| C.cpp:24:5:24:25 | ... = ... [void] | C.cpp:24:5:24:8 | this [post update] [s3, ... (1)] |
89+
| C.cpp:24:16:24:25 | new [void] | C.cpp:24:5:24:25 | ... = ... [void] |
90+
| C.cpp:27:8:27:11 | `this` parameter in func [s3, ... (1)] | file://:0:0:0:0 | this [s3, ... (1)] |
91+
| file://:0:0:0:0 | this [s3, ... (1)] | C.cpp:31:10:31:11 | s3 |
92+
#select
93+
| A.cpp:43:10:43:12 | & ... | A.cpp:41:10:41:16 | new [void] | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:10:41:16 | new [void] | new [void] |
94+
| A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new [void] | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new [void] | new [void] |
95+
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | new [void] | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new [void] | new [void] |
96+
| A.cpp:57:28:57:30 | call to get | A.cpp:57:17:57:23 | new [void] | A.cpp:57:28:57:30 | call to get | call to get flows from $@ | A.cpp:57:17:57:23 | new [void] | new [void] |
97+
| A.cpp:66:14:66:14 | c | A.cpp:64:21:64:28 | new [void] | A.cpp:66:14:66:14 | c | c flows from $@ | A.cpp:64:21:64:28 | new [void] | new [void] |
98+
| A.cpp:75:14:75:14 | c | A.cpp:73:25:73:32 | new [void] | A.cpp:75:14:75:14 | c | c flows from $@ | A.cpp:73:25:73:32 | new [void] | new [void] |
99+
| A.cpp:107:16:107:16 | a | A.cpp:98:12:98:18 | new [void] | A.cpp:107:16:107:16 | a | a flows from $@ | A.cpp:98:12:98:18 | new [void] | new [void] |
100+
| A.cpp:120:16:120:16 | a | A.cpp:98:12:98:18 | new [void] | A.cpp:120:16:120:16 | a | a flows from $@ | A.cpp:98:12:98:18 | new [void] | new [void] |
101+
| A.cpp:132:13:132:13 | c | A.cpp:126:12:126:18 | new [void] | A.cpp:132:13:132:13 | c | c flows from $@ | A.cpp:126:12:126:18 | new [void] | new [void] |
102+
| A.cpp:152:13:152:13 | b | A.cpp:143:25:143:31 | new [void] | A.cpp:152:13:152:13 | b | b flows from $@ | A.cpp:143:25:143:31 | new [void] | new [void] |
103+
| A.cpp:152:13:152:13 | b | A.cpp:150:12:150:18 | new [void] | A.cpp:152:13:152:13 | b | b flows from $@ | A.cpp:150:12:150:18 | new [void] | new [void] |
104+
| A.cpp:153:16:153:16 | c | A.cpp:142:14:142:20 | new [void] | A.cpp:153:16:153:16 | c | c flows from $@ | A.cpp:142:14:142:20 | new [void] | new [void] |
105+
| A.cpp:154:13:154:13 | c | A.cpp:142:14:142:20 | new [void] | A.cpp:154:13:154:13 | c | c flows from $@ | A.cpp:142:14:142:20 | new [void] | new [void] |
106+
| A.cpp:165:26:165:29 | head | A.cpp:159:12:159:18 | new [void] | A.cpp:165:26:165:29 | head | head flows from $@ | A.cpp:159:12:159:18 | new [void] | new [void] |
107+
| A.cpp:169:15:169:18 | head | A.cpp:159:12:159:18 | new [void] | A.cpp:169:15:169:18 | head | head flows from $@ | A.cpp:159:12:159:18 | new [void] | new [void] |
108+
| B.cpp:9:20:9:24 | elem1 | B.cpp:6:15:6:24 | new [void] | B.cpp:9:20:9:24 | elem1 | elem1 flows from $@ | B.cpp:6:15:6:24 | new [void] | new [void] |
109+
| 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] |
110+
| 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] |
111+
| 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] |
112+
| 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] |

0 commit comments

Comments
 (0)