1 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true,cfg-temporary-dtors=false,cfg-rich-constructors=false -analyzer-config cfg-implicit-dtors=false %s > %t 2>&1 |
2 | // RUN: FileCheck --input-file=%t %s |
3 | |
4 | extern bool UV; |
5 | class A { |
6 | public: |
7 | // CHECK: [B2 (ENTRY)] |
8 | // CHECK-NEXT: Succs (1): B1 |
9 | // CHECK: [B1] |
10 | // CHECK-NEXT: 1: true |
11 | // CHECK-NEXT: 2: UV |
12 | // CHECK-NEXT: 3: [B1.2] = [B1.1] |
13 | // CHECK-NEXT: Preds (1): B2 |
14 | // CHECK-NEXT: Succs (1): B0 |
15 | // CHECK: [B0 (EXIT)] |
16 | // CHECK-NEXT: Preds (1): B1 |
17 | A() { |
18 | UV = true; |
19 | } |
20 | // CHECK: [B3 (ENTRY)] |
21 | // CHECK-NEXT: Succs (1): B2 |
22 | // CHECK: [B1] |
23 | // CHECK-NEXT: 1: 0 |
24 | // CHECK-NEXT: 2: this |
25 | // CHECK-NEXT: 3: [B1.2]->p |
26 | // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, LValueToRValue, int *) |
27 | // CHECK-NEXT: 5: *[B1.4] |
28 | // CHECK-NEXT: 6: [B1.5] = [B1.1] |
29 | // CHECK-NEXT: Preds (1): B2 |
30 | // CHECK-NEXT: Succs (1): B0 |
31 | // CHECK: [B2] |
32 | // CHECK-NEXT: 1: this |
33 | // CHECK-NEXT: 2: [B2.1]->p |
34 | // CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *) |
35 | // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, PointerToBoolean, _Bool) |
36 | // CHECK-NEXT: T: if [B2.4] |
37 | // CHECK-NEXT: Preds (1): B3 |
38 | // CHECK-NEXT: Succs (2): B1 B0 |
39 | // CHECK: [B0 (EXIT)] |
40 | // CHECK-NEXT: Preds (2): B1 B2 |
41 | ~A() { |
42 | if (p) |
43 | *p = 0; |
44 | } |
45 | // CHECK: [B2 (ENTRY)] |
46 | // CHECK-NEXT: Succs (1): B1 |
47 | // CHECK: [B1] |
48 | // CHECK-NEXT: 1: 1 |
49 | // CHECK-NEXT: 2: return [B1.1]; |
50 | // CHECK-NEXT: Preds (1): B2 |
51 | // CHECK-NEXT: Succs (1): B0 |
52 | // CHECK: [B0 (EXIT)] |
53 | // CHECK-NEXT: Preds (1): B1 |
54 | operator int() const { return 1; } |
55 | int *p; |
56 | }; |
57 | |
58 | // CHECK: [B2 (ENTRY)] |
59 | // CHECK-NEXT: Succs (1): B1 |
60 | // CHECK: [B1] |
61 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
62 | // CHECK-NEXT: 2: A a; |
63 | // CHECK-NEXT: 3: a |
64 | // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class A) |
65 | // CHECK-NEXT: 5: const A &b = a; |
66 | // CHECK-NEXT: 6: A() (CXXConstructExpr, class A) |
67 | // CHECK-NEXT: 7: [B1.6] (BindTemporary) |
68 | // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) |
69 | // CHECK-NEXT: 9: [B1.8] |
70 | // CHECK-NEXT: 10: const A &c = A(); |
71 | // CHECK-NEXT: 11: [B1.10] (Lifetime ends) |
72 | // CHECK-NEXT: 12: [B1.2] (Lifetime ends) |
73 | // CHECK-NEXT: 13: [B1.5] (Lifetime ends) |
74 | // CHECK-NEXT: Preds (1): B2 |
75 | // CHECK-NEXT: Succs (1): B0 |
76 | // CHECK: [B0 (EXIT)] |
77 | // CHECK-NEXT: Preds (1): B1 |
78 | void test_const_ref() { |
79 | A a; |
80 | const A &b = a; |
81 | const A &c = A(); |
82 | } |
83 | |
84 | // CHECK: [B2 (ENTRY)] |
85 | // CHECK-NEXT: Succs (1): B1 |
86 | // CHECK: [B1] |
87 | // CHECK-NEXT: 1: (CXXConstructExpr, class A [2]) |
88 | // CHECK-NEXT: 2: A a[2]; |
89 | // CHECK-NEXT: 3: (CXXConstructExpr, class A [0]) |
90 | // CHECK-NEXT: 4: A b[0]; |
91 | // lifetime of a ends when its destructors are run |
92 | // CHECK-NEXT: 5: [B1.2] (Lifetime ends) |
93 | // lifetime of b ends when its storage duration ends |
94 | // CHECK-NEXT: 6: [B1.4] (Lifetime ends) |
95 | // CHECK-NEXT: Preds (1): B2 |
96 | // CHECK-NEXT: Succs (1): B0 |
97 | // CHECK: [B0 (EXIT)] |
98 | // CHECK-NEXT: Preds (1): B1 |
99 | void test_array() { |
100 | A a[2]; |
101 | A b[0]; |
102 | } |
103 | |
104 | // CHECK: [B2 (ENTRY)] |
105 | // CHECK-NEXT: Succs (1): B1 |
106 | // CHECK: [B1] |
107 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
108 | // CHECK-NEXT: 2: A a; |
109 | // CHECK-NEXT: 3: (CXXConstructExpr, class A) |
110 | // CHECK-NEXT: 4: A c; |
111 | // CHECK-NEXT: 5: (CXXConstructExpr, class A) |
112 | // CHECK-NEXT: 6: A d; |
113 | // CHECK-NEXT: 7: [B1.6] (Lifetime ends) |
114 | // CHECK-NEXT: 8: [B1.4] (Lifetime ends) |
115 | // CHECK-NEXT: 9: (CXXConstructExpr, class A) |
116 | // CHECK-NEXT: 10: A b; |
117 | // CHECK-NEXT: 11: [B1.10] (Lifetime ends) |
118 | // CHECK-NEXT: 12: [B1.2] (Lifetime ends) |
119 | // CHECK-NEXT: Preds (1): B2 |
120 | // CHECK-NEXT: Succs (1): B0 |
121 | // CHECK: [B0 (EXIT)] |
122 | // CHECK-NEXT: Preds (1): B1 |
123 | void test_scope() { |
124 | A a; |
125 | { |
126 | A c; |
127 | A d; |
128 | } |
129 | A b; |
130 | } |
131 | |
132 | // CHECK: [B4 (ENTRY)] |
133 | // CHECK-NEXT: Succs (1): B3 |
134 | // CHECK: [B1] |
135 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
136 | // CHECK-NEXT: 2: A c; |
137 | // CHECK-NEXT: 3: [B1.2] (Lifetime ends) |
138 | // CHECK-NEXT: 4: [B3.4] (Lifetime ends) |
139 | // CHECK-NEXT: 5: [B3.2] (Lifetime ends) |
140 | // CHECK-NEXT: Preds (1): B3 |
141 | // CHECK-NEXT: Succs (1): B0 |
142 | // CHECK: [B2] |
143 | // CHECK-NEXT: 1: return; |
144 | // CHECK-NEXT: 2: [B3.4] (Lifetime ends) |
145 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
146 | // CHECK-NEXT: Preds (1): B3 |
147 | // CHECK-NEXT: Succs (1): B0 |
148 | // CHECK: [B3] |
149 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
150 | // CHECK-NEXT: 2: A a; |
151 | // CHECK-NEXT: 3: (CXXConstructExpr, class A) |
152 | // CHECK-NEXT: 4: A b; |
153 | // CHECK-NEXT: 5: UV |
154 | // CHECK-NEXT: 6: [B3.5] (ImplicitCastExpr, LValueToRValue, _Bool) |
155 | // CHECK-NEXT: T: if [B3.6] |
156 | // CHECK-NEXT: Preds (1): B4 |
157 | // CHECK-NEXT: Succs (2): B2 B1 |
158 | |
159 | // CHECK: [B0 (EXIT)] |
160 | // CHECK-NEXT: Preds (2): B1 B2 |
161 | void test_return() { |
162 | A a; |
163 | A b; |
164 | if (UV) |
165 | return; |
166 | A c; |
167 | } |
168 | |
169 | // CHECK: [B5 (ENTRY)] |
170 | // CHECK-NEXT: Succs (1): B4 |
171 | // CHECK: [B1] |
172 | // CHECK-NEXT: 1: [B4.6] (Lifetime ends) |
173 | // CHECK-NEXT: 2: [B4.2] (Lifetime ends) |
174 | // CHECK-NEXT: Preds (2): B2 B3 |
175 | // CHECK-NEXT: Succs (1): B0 |
176 | // CHECK: [B2] |
177 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
178 | // CHECK-NEXT: 2: A c; |
179 | // CHECK-NEXT: 3: [B2.2] (Lifetime ends) |
180 | // CHECK-NEXT: Preds (1): B4 |
181 | // CHECK-NEXT: Succs (1): B1 |
182 | // CHECK: [B3] |
183 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
184 | // CHECK-NEXT: 2: A c; |
185 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
186 | // CHECK-NEXT: Preds (1): B4 |
187 | // CHECK-NEXT: Succs (1): B1 |
188 | // CHECK: [B4] |
189 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
190 | // CHECK-NEXT: 2: A a; |
191 | // CHECK-NEXT: 3: a |
192 | // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, NoOp, const class A) |
193 | // CHECK-NEXT: 5: [B4.4] (CXXConstructExpr, class A) |
194 | // CHECK-NEXT: 6: A b = a; |
195 | // CHECK-NEXT: 7: b |
196 | // CHECK-NEXT: 8: [B4.7] (ImplicitCastExpr, NoOp, const class A) |
197 | // CHECK-NEXT: 9: [B4.8].operator int |
198 | // CHECK-NEXT: 10: [B4.8] |
199 | // CHECK-NEXT: 11: [B4.10] (ImplicitCastExpr, UserDefinedConversion, int) |
200 | // CHECK-NEXT: 12: [B4.11] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
201 | // CHECK-NEXT: T: if [B4.12] |
202 | // CHECK-NEXT: Preds (1): B5 |
203 | // CHECK-NEXT: Succs (2): B3 B2 |
204 | // CHECK: [B0 (EXIT)] |
205 | // CHECK-NEXT: Preds (1): B1 |
206 | void test_if_implicit_scope() { |
207 | A a; |
208 | if (A b = a) |
209 | A c; |
210 | else |
211 | A c; |
212 | } |
213 | |
214 | // CHECK: [B9 (ENTRY)] |
215 | // CHECK-NEXT: Succs (1): B8 |
216 | // CHECK: [B1] |
217 | // CHECK-NEXT: 1: [B8.6] (Lifetime ends) |
218 | // CHECK-NEXT: 2: (CXXConstructExpr, class A) |
219 | // CHECK-NEXT: 3: A e; |
220 | // CHECK-NEXT: 4: [B1.3] (Lifetime ends) |
221 | // CHECK-NEXT: 5: [B8.2] (Lifetime ends) |
222 | // CHECK-NEXT: Preds (2): B2 B5 |
223 | // CHECK-NEXT: Succs (1): B0 |
224 | // CHECK: [B2] |
225 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
226 | // CHECK-NEXT: 2: A d; |
227 | // CHECK-NEXT: 3: [B2.2] (Lifetime ends) |
228 | // CHECK-NEXT: 4: [B4.2] (Lifetime ends) |
229 | // CHECK-NEXT: Preds (1): B4 |
230 | // CHECK-NEXT: Succs (1): B1 |
231 | // CHECK: [B3] |
232 | // CHECK-NEXT: 1: return; |
233 | // CHECK-NEXT: 2: [B4.2] (Lifetime ends) |
234 | // CHECK-NEXT: 3: [B8.6] (Lifetime ends) |
235 | // CHECK-NEXT: 4: [B8.2] (Lifetime ends) |
236 | // CHECK-NEXT: Preds (1): B4 |
237 | // CHECK-NEXT: Succs (1): B0 |
238 | // CHECK: [B4] |
239 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
240 | // CHECK-NEXT: 2: A c; |
241 | // CHECK-NEXT: 3: UV |
242 | // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
243 | // CHECK-NEXT: T: if [B4.4] |
244 | // CHECK-NEXT: Preds (1): B8 |
245 | // CHECK-NEXT: Succs (2): B3 B2 |
246 | // CHECK: [B5] |
247 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
248 | // CHECK-NEXT: 2: A d; |
249 | // CHECK-NEXT: 3: [B5.2] (Lifetime ends) |
250 | // CHECK-NEXT: 4: [B7.2] (Lifetime ends) |
251 | // CHECK-NEXT: Preds (1): B7 |
252 | // CHECK-NEXT: Succs (1): B1 |
253 | // CHECK: [B6] |
254 | // CHECK-NEXT: 1: return; |
255 | // CHECK-NEXT: 2: [B7.2] (Lifetime ends) |
256 | // CHECK-NEXT: 3: [B8.6] (Lifetime ends) |
257 | // CHECK-NEXT: 4: [B8.2] (Lifetime ends) |
258 | // CHECK-NEXT: Preds (1): B7 |
259 | // CHECK-NEXT: Succs (1): B0 |
260 | // CHECK: [B7] |
261 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
262 | // CHECK-NEXT: 2: A c; |
263 | // CHECK-NEXT: 3: UV |
264 | // CHECK-NEXT: 4: [B7.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
265 | // CHECK-NEXT: T: if [B7.4] |
266 | // CHECK-NEXT: Preds (1): B8 |
267 | // CHECK-NEXT: Succs (2): B6 B5 |
268 | // CHECK: [B8] |
269 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
270 | // CHECK-NEXT: 2: A a; |
271 | // CHECK-NEXT: 3: a |
272 | // CHECK-NEXT: 4: [B8.3] (ImplicitCastExpr, NoOp, const class A) |
273 | // CHECK-NEXT: 5: [B8.4] (CXXConstructExpr, class A) |
274 | // CHECK-NEXT: 6: A b = a; |
275 | // CHECK-NEXT: 7: b |
276 | // CHECK-NEXT: 8: [B8.7] (ImplicitCastExpr, NoOp, const class A) |
277 | // CHECK-NEXT: 9: [B8.8].operator int |
278 | // CHECK-NEXT: 10: [B8.8] |
279 | // CHECK-NEXT: 11: [B8.10] (ImplicitCastExpr, UserDefinedConversion, int) |
280 | // CHECK-NEXT: 12: [B8.11] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
281 | // CHECK-NEXT: T: if [B8.12] |
282 | // CHECK-NEXT: Preds (1): B9 |
283 | // CHECK-NEXT: Succs (2): B7 B4 |
284 | // CHECK: [B0 (EXIT)] |
285 | // CHECK-NEXT: Preds (3): B1 B3 B6 |
286 | void test_if_jumps() { |
287 | A a; |
288 | if (A b = a) { |
289 | A c; |
290 | if (UV) |
291 | return; |
292 | A d; |
293 | } else { |
294 | A c; |
295 | if (UV) |
296 | return; |
297 | A d; |
298 | } |
299 | A e; |
300 | } |
301 | |
302 | // CHECK: [B6 (ENTRY)] |
303 | // CHECK-NEXT: Succs (1): B5 |
304 | // CHECK: [B1] |
305 | // CHECK-NEXT: 1: [B4.4] (Lifetime ends) |
306 | // CHECK-NEXT: 2: [B5.2] (Lifetime ends) |
307 | // CHECK-NEXT: Preds (1): B4 |
308 | // CHECK-NEXT: Succs (1): B0 |
309 | // CHECK: [B2] |
310 | // CHECK-NEXT: Preds (1): B3 |
311 | // CHECK-NEXT: Succs (1): B4 |
312 | // CHECK: [B3] |
313 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
314 | // CHECK-NEXT: 2: A c; |
315 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
316 | // CHECK-NEXT: 4: [B4.4] (Lifetime ends) |
317 | // CHECK-NEXT: Preds (1): B4 |
318 | // CHECK-NEXT: Succs (1): B2 |
319 | // CHECK: [B4] |
320 | // CHECK-NEXT: 1: a |
321 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) |
322 | // CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A) |
323 | // CHECK-NEXT: 4: A b = a; |
324 | // CHECK-NEXT: 5: b |
325 | // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) |
326 | // CHECK-NEXT: 7: [B4.6].operator int |
327 | // CHECK-NEXT: 8: [B4.6] |
328 | // CHECK-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) |
329 | // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
330 | // CHECK-NEXT: T: while [B4.10] |
331 | // CHECK-NEXT: Preds (2): B2 B5 |
332 | // CHECK-NEXT: Succs (2): B3 B1 |
333 | // CHECK: [B5] |
334 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
335 | // CHECK-NEXT: 2: A a; |
336 | // CHECK-NEXT: Preds (1): B6 |
337 | // CHECK-NEXT: Succs (1): B4 |
338 | // CHECK: [B0 (EXIT)] |
339 | // CHECK-NEXT: Preds (1): B1 |
340 | void test_while_implicit_scope() { |
341 | A a; |
342 | while (A b = a) |
343 | A c; |
344 | } |
345 | |
346 | // CHECK: [B12 (ENTRY)] |
347 | // CHECK-NEXT: Succs (1): B11 |
348 | // CHECK: [B1] |
349 | // CHECK-NEXT: 1: [B10.4] (Lifetime ends) |
350 | // CHECK-NEXT: 2: (CXXConstructExpr, class A) |
351 | // CHECK-NEXT: 3: A e; |
352 | // CHECK-NEXT: 4: [B1.3] (Lifetime ends) |
353 | // CHECK-NEXT: 5: [B11.2] (Lifetime ends) |
354 | // CHECK-NEXT: Preds (2): B8 B10 |
355 | // CHECK-NEXT: Succs (1): B0 |
356 | // CHECK: [B2] |
357 | // CHECK-NEXT: Preds (2): B3 B6 |
358 | // CHECK-NEXT: Succs (1): B10 |
359 | // CHECK: [B3] |
360 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
361 | // CHECK-NEXT: 2: A d; |
362 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
363 | // CHECK-NEXT: 4: [B9.2] (Lifetime ends) |
364 | // CHECK-NEXT: 5: [B10.4] (Lifetime ends) |
365 | // CHECK-NEXT: Preds (1): B5 |
366 | // CHECK-NEXT: Succs (1): B2 |
367 | // CHECK: [B4] |
368 | // CHECK-NEXT: 1: return; |
369 | // CHECK-NEXT: 2: [B9.2] (Lifetime ends) |
370 | // CHECK-NEXT: 3: [B10.4] (Lifetime ends) |
371 | // CHECK-NEXT: 4: [B11.2] (Lifetime ends) |
372 | // CHECK-NEXT: Preds (1): B5 |
373 | // CHECK-NEXT: Succs (1): B0 |
374 | // CHECK: [B5] |
375 | // CHECK-NEXT: 1: UV |
376 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
377 | // CHECK-NEXT: T: if [B5.2] |
378 | // CHECK-NEXT: Preds (1): B7 |
379 | // CHECK-NEXT: Succs (2): B4 B3 |
380 | // CHECK: [B6] |
381 | // CHECK-NEXT: 1: [B9.2] (Lifetime ends) |
382 | // CHECK-NEXT: 2: [B10.4] (Lifetime ends) |
383 | // CHECK-NEXT: T: continue; |
384 | // CHECK-NEXT: Preds (1): B7 |
385 | // CHECK-NEXT: Succs (1): B2 |
386 | // CHECK: [B7] |
387 | // CHECK-NEXT: 1: UV |
388 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
389 | // CHECK-NEXT: T: if [B7.2] |
390 | // CHECK-NEXT: Preds (1): B9 |
391 | // CHECK-NEXT: Succs (2): B6 B5 |
392 | // CHECK: [B8] |
393 | // CHECK-NEXT: 1: [B9.2] (Lifetime ends) |
394 | // CHECK-NEXT: T: break; |
395 | // CHECK-NEXT: Preds (1): B9 |
396 | // CHECK-NEXT: Succs (1): B1 |
397 | // CHECK: [B9] |
398 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
399 | // CHECK-NEXT: 2: A c; |
400 | // CHECK-NEXT: 3: UV |
401 | // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
402 | // CHECK-NEXT: T: if [B9.4] |
403 | // CHECK-NEXT: Preds (1): B10 |
404 | // CHECK-NEXT: Succs (2): B8 B7 |
405 | // CHECK: [B10] |
406 | // CHECK-NEXT: 1: a |
407 | // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) |
408 | // CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A) |
409 | // CHECK-NEXT: 4: A b = a; |
410 | // CHECK-NEXT: 5: b |
411 | // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) |
412 | // CHECK-NEXT: 7: [B10.6].operator int |
413 | // CHECK-NEXT: 8: [B10.6] |
414 | // CHECK-NEXT: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) |
415 | // CHECK-NEXT: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
416 | // CHECK-NEXT: T: while [B10.10] |
417 | // CHECK-NEXT: Preds (2): B2 B11 |
418 | // CHECK-NEXT: Succs (2): B9 B1 |
419 | // CHECK: [B11] |
420 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
421 | // CHECK-NEXT: 2: A a; |
422 | // CHECK-NEXT: Preds (1): B12 |
423 | // CHECK-NEXT: Succs (1): B10 |
424 | // CHECK: [B0 (EXIT)] |
425 | // CHECK-NEXT: Preds (2): B1 B4 |
426 | void test_while_jumps() { |
427 | A a; |
428 | while (A b = a) { |
429 | A c; |
430 | if (UV) |
431 | break; |
432 | if (UV) |
433 | continue; |
434 | if (UV) |
435 | return; |
436 | A d; |
437 | } |
438 | A e; |
439 | } |
440 | |
441 | // CHECK: [B12 (ENTRY)] |
442 | // CHECK-NEXT: Succs (1): B11 |
443 | // CHECK: [B1] |
444 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
445 | // CHECK-NEXT: 2: A d; |
446 | // CHECK-NEXT: 3: [B1.2] (Lifetime ends) |
447 | // CHECK-NEXT: 4: [B11.2] (Lifetime ends) |
448 | // CHECK-NEXT: Preds (2): B8 B2 |
449 | // CHECK-NEXT: Succs (1): B0 |
450 | // CHECK: [B2] |
451 | // CHECK-NEXT: 1: UV |
452 | // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
453 | // CHECK-NEXT: T: do ... while [B2.2] |
454 | // CHECK-NEXT: Preds (2): B3 B6 |
455 | // CHECK-NEXT: Succs (2): B10 B1 |
456 | // CHECK: [B3] |
457 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
458 | // CHECK-NEXT: 2: A c; |
459 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
460 | // CHECK-NEXT: 4: [B9.2] (Lifetime ends) |
461 | // CHECK-NEXT: Preds (1): B5 |
462 | // CHECK-NEXT: Succs (1): B2 |
463 | // CHECK: [B4] |
464 | // CHECK-NEXT: 1: return; |
465 | // CHECK-NEXT: 2: [B9.2] (Lifetime ends) |
466 | // CHECK-NEXT: 3: [B11.2] (Lifetime ends) |
467 | // CHECK-NEXT: Preds (1): B5 |
468 | // CHECK-NEXT: Succs (1): B0 |
469 | // CHECK: [B5] |
470 | // CHECK-NEXT: 1: UV |
471 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
472 | // CHECK-NEXT: T: if [B5.2] |
473 | // CHECK-NEXT: Preds (1): B7 |
474 | // CHECK-NEXT: Succs (2): B4 B3 |
475 | // CHECK: [B6] |
476 | // CHECK-NEXT: 1: [B9.2] (Lifetime ends) |
477 | // CHECK-NEXT: T: continue; |
478 | // CHECK-NEXT: Preds (1): B7 |
479 | // CHECK-NEXT: Succs (1): B2 |
480 | // CHECK: [B7] |
481 | // CHECK-NEXT: 1: UV |
482 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
483 | // CHECK-NEXT: T: if [B7.2] |
484 | // CHECK-NEXT: Preds (1): B9 |
485 | // CHECK-NEXT: Succs (2): B6 B5 |
486 | // CHECK: [B8] |
487 | // CHECK-NEXT: 1: [B9.2] (Lifetime ends) |
488 | // CHECK-NEXT: T: break; |
489 | // CHECK-NEXT: Preds (1): B9 |
490 | // CHECK-NEXT: Succs (1): B1 |
491 | // CHECK: [B9] |
492 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
493 | // CHECK-NEXT: 2: A b; |
494 | // CHECK-NEXT: 3: UV |
495 | // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
496 | // CHECK-NEXT: T: if [B9.4] |
497 | // CHECK-NEXT: Preds (2): B10 B11 |
498 | // CHECK-NEXT: Succs (2): B8 B7 |
499 | // CHECK: [B10] |
500 | // CHECK-NEXT: Preds (1): B2 |
501 | // CHECK-NEXT: Succs (1): B9 |
502 | // CHECK: [B11] |
503 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
504 | // CHECK-NEXT: 2: A a; |
505 | // CHECK-NEXT: Preds (1): B12 |
506 | // CHECK-NEXT: Succs (1): B9 |
507 | // CHECK: [B0 (EXIT)] |
508 | // CHECK-NEXT: Preds (2): B1 B4 |
509 | void test_do_jumps() { |
510 | A a; |
511 | do { |
512 | A b; |
513 | if (UV) |
514 | break; |
515 | if (UV) |
516 | continue; |
517 | if (UV) |
518 | return; |
519 | A c; |
520 | } while (UV); |
521 | A d; |
522 | } |
523 | |
524 | // CHECK: [B6 (ENTRY)] |
525 | // CHECK-NEXT: Succs (1): B5 |
526 | // CHECK: [B1] |
527 | // CHECK-NEXT: 1: [B4.4] (Lifetime ends) |
528 | // CHECK-NEXT: 2: [B5.2] (Lifetime ends) |
529 | // CHECK-NEXT: Preds (1): B4 |
530 | // CHECK-NEXT: Succs (1): B0 |
531 | // CHECK: [B2] |
532 | // CHECK-NEXT: Preds (1): B3 |
533 | // CHECK-NEXT: Succs (1): B4 |
534 | // CHECK: [B3] |
535 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
536 | // CHECK-NEXT: 2: A c; |
537 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
538 | // CHECK-NEXT: 4: [B4.4] (Lifetime ends) |
539 | // CHECK-NEXT: Preds (1): B4 |
540 | // CHECK-NEXT: Succs (1): B2 |
541 | // CHECK: [B4] |
542 | // CHECK-NEXT: 1: a |
543 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) |
544 | // CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A) |
545 | // CHECK-NEXT: 4: A b = a; |
546 | // CHECK-NEXT: 5: b |
547 | // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) |
548 | // CHECK-NEXT: 7: [B4.6].operator int |
549 | // CHECK-NEXT: 8: [B4.6] |
550 | // CHECK-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) |
551 | // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
552 | // CHECK-NEXT: T: for (...; [B4.10]; ) |
553 | // CHECK-NEXT: Preds (2): B2 B5 |
554 | // CHECK-NEXT: Succs (2): B3 B1 |
555 | // CHECK: [B5] |
556 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
557 | // CHECK-NEXT: 2: A a; |
558 | // CHECK-NEXT: Preds (1): B6 |
559 | // CHECK-NEXT: Succs (1): B4 |
560 | // CHECK: [B0 (EXIT)] |
561 | // CHECK-NEXT: Preds (1): B1 |
562 | void test_for_implicit_scope() { |
563 | for (A a; A b = a;) |
564 | A c; |
565 | } |
566 | |
567 | // CHECK: [B12 (ENTRY)] |
568 | // CHECK-NEXT: Succs (1): B11 |
569 | // CHECK: [B1] |
570 | // CHECK-NEXT: 1: [B10.4] (Lifetime ends) |
571 | // CHECK-NEXT: 2: [B11.4] (Lifetime ends) |
572 | // CHECK-NEXT: 3: (CXXConstructExpr, class A) |
573 | // CHECK-NEXT: 4: A f; |
574 | // CHECK-NEXT: 5: [B1.4] (Lifetime ends) |
575 | // CHECK-NEXT: 6: [B11.2] (Lifetime ends) |
576 | // CHECK-NEXT: Preds (2): B8 B10 |
577 | // CHECK-NEXT: Succs (1): B0 |
578 | // CHECK: [B2] |
579 | // CHECK-NEXT: Preds (2): B3 B6 |
580 | // CHECK-NEXT: Succs (1): B10 |
581 | // CHECK: [B3] |
582 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
583 | // CHECK-NEXT: 2: A e; |
584 | // CHECK-NEXT: 3: [B3.2] (Lifetime ends) |
585 | // CHECK-NEXT: 4: [B9.2] (Lifetime ends) |
586 | // CHECK-NEXT: 5: [B10.4] (Lifetime ends) |
587 | // CHECK-NEXT: Preds (1): B5 |
588 | // CHECK-NEXT: Succs (1): B2 |
589 | // CHECK: [B4] |
590 | // CHECK-NEXT: 1: return; |
591 | // CHECK-NEXT: 2: [B9.2] (Lifetime ends) |
592 | // CHECK-NEXT: 3: [B10.4] (Lifetime ends) |
593 | // CHECK-NEXT: 4: [B11.4] (Lifetime ends) |
594 | // CHECK-NEXT: 5: [B11.2] (Lifetime ends) |
595 | // CHECK-NEXT: Preds (1): B5 |
596 | // CHECK-NEXT: Succs (1): B0 |
597 | // CHECK: [B5] |
598 | // CHECK-NEXT: 1: UV |
599 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
600 | // CHECK-NEXT: T: if [B5.2] |
601 | // CHECK-NEXT: Preds (1): B7 |
602 | // CHECK-NEXT: Succs (2): B4 B3 |
603 | // CHECK: [B6] |
604 | // CHECK-NEXT: 1: [B9.2] (Lifetime ends) |
605 | // CHECK-NEXT: T: continue; |
606 | // CHECK-NEXT: Preds (1): B7 |
607 | // CHECK-NEXT: Succs (1): B2 |
608 | // CHECK: [B7] |
609 | // CHECK-NEXT: 1: UV |
610 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
611 | // CHECK-NEXT: T: if [B7.2] |
612 | // CHECK-NEXT: Preds (1): B9 |
613 | // CHECK-NEXT: Succs (2): B6 B5 |
614 | // CHECK: [B8] |
615 | // CHECK-NEXT: 1: [B9.2] (Lifetime ends) |
616 | // CHECK-NEXT: T: break; |
617 | // CHECK-NEXT: Preds (1): B9 |
618 | // CHECK-NEXT: Succs (1): B1 |
619 | // CHECK: [B9] |
620 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
621 | // CHECK-NEXT: 2: A d; |
622 | // CHECK-NEXT: 3: UV |
623 | // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
624 | // CHECK-NEXT: T: if [B9.4] |
625 | // CHECK-NEXT: Preds (1): B10 |
626 | // CHECK-NEXT: Succs (2): B8 B7 |
627 | // CHECK: [B10] |
628 | // CHECK-NEXT: 1: b |
629 | // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) |
630 | // CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A) |
631 | // CHECK-NEXT: 4: A c = b; |
632 | // CHECK-NEXT: 5: c |
633 | // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) |
634 | // CHECK-NEXT: 7: [B10.6].operator int |
635 | // CHECK-NEXT: 8: [B10.6] |
636 | // CHECK-NEXT: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) |
637 | // CHECK-NEXT: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
638 | // CHECK-NEXT: T: for (...; [B10.10]; ) |
639 | // CHECK-NEXT: Preds (2): B2 B11 |
640 | // CHECK-NEXT: Succs (2): B9 B1 |
641 | // CHECK: [B11] |
642 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
643 | // CHECK-NEXT: 2: A a; |
644 | // CHECK-NEXT: 3: (CXXConstructExpr, class A) |
645 | // CHECK-NEXT: 4: A b; |
646 | // CHECK-NEXT: Preds (1): B12 |
647 | // CHECK-NEXT: Succs (1): B10 |
648 | // CHECK: [B0 (EXIT)] |
649 | // CHECK-NEXT: Preds (2): B1 B4 |
650 | void test_for_jumps() { |
651 | A a; |
652 | for (A b; A c = b;) { |
653 | A d; |
654 | if (UV) |
655 | break; |
656 | if (UV) |
657 | continue; |
658 | if (UV) |
659 | return; |
660 | A e; |
661 | } |
662 | A f; |
663 | } |
664 | |
665 | // CHECK: [B2 (ENTRY)] |
666 | // CHECK-NEXT: Succs (1): B1 |
667 | // CHECK: [B1] |
668 | // CHECK-NEXT: 1: (CXXConstructExpr, class A) |
669 | // CHECK-NEXT: 2: A a; |
670 | // CHECK-NEXT: 3: int n; |
671 | // CHECK-NEXT: 4: n |
672 | // CHECK-NEXT: 5: &[B1.4] |
673 | // CHECK-NEXT: 6: a |
674 | // CHECK-NEXT: 7: [B1.6].p |
675 | // CHECK-NEXT: 8: [B1.7] = [B1.5] |
676 | // CHECK-NEXT: 9: [B1.2] (Lifetime ends) |
677 | // CHECK-NEXT: 10: [B1.3] (Lifetime ends) |
678 | // CHECK-NEXT: Preds (1): B2 |
679 | // CHECK-NEXT: Succs (1): B0 |
680 | // CHECK: [B0 (EXIT)] |
681 | // CHECK-NEXT: Preds (1): B1 |
682 | void test_trivial_vs_non_trivial_order() { |
683 | A a; |
684 | int n; |
685 | a.p = &n; |
686 | } |
687 | |
688 | // CHECK: [B4 (ENTRY)] |
689 | // CHECK-NEXT: Succs (1): B3 |
690 | // CHECK: [B1] |
691 | // CHECK-NEXT: a: |
692 | // CHECK-NEXT: 1: 1 |
693 | // CHECK-NEXT: 2: i |
694 | // CHECK-NEXT: 3: [B1.2] = [B1.1] |
695 | // CHECK-NEXT: 4: [B2.1] (Lifetime ends) |
696 | // CHECK-NEXT: Preds (2): B2 B3 |
697 | // CHECK-NEXT: Succs (1): B0 |
698 | // CHECK: [B2] |
699 | // CHECK-NEXT: 1: int i; |
700 | // CHECK-NEXT: Succs (1): B1 |
701 | // CHECK: [B3] |
702 | // CHECK-NEXT: T: goto a; |
703 | // CHECK-NEXT: Preds (1): B4 |
704 | // CHECK-NEXT: Succs (1): B1 |
705 | // CHECK: [B0 (EXIT)] |
706 | // CHECK-NEXT: Preds (1): B1 |
707 | void goto_past_declaration() { |
708 | goto a; |
709 | int i; |
710 | a: |
711 | i = 1; |
712 | } |
713 | |
714 | // CHECK: [B4 (ENTRY)] |
715 | // CHECK-NEXT: Succs (1): B3 |
716 | // CHECK: [B1] |
717 | // CHECK-NEXT: a: |
718 | // CHECK-NEXT: 1: 1 |
719 | // CHECK-NEXT: 2: k |
720 | // CHECK-NEXT: 3: [B1.2] = [B1.1] |
721 | // CHECK-NEXT: 4: [B2.4] (Lifetime ends) |
722 | // CHECK-NEXT: Preds (2): B2 B3 |
723 | // CHECK-NEXT: Succs (1): B0 |
724 | // CHECK: [B2] |
725 | // CHECK-NEXT: 1: int j; |
726 | // CHECK-NEXT: 2: [B2.1] (Lifetime ends) |
727 | // CHECK-NEXT: 3: [B3.1] (Lifetime ends) |
728 | // CHECK-NEXT: 4: int k; |
729 | // CHECK-NEXT: Succs (1): B1 |
730 | // CHECK: [B3] |
731 | // CHECK-NEXT: 1: int i; |
732 | // CHECK-NEXT: 2: [B3.1] (Lifetime ends) |
733 | // CHECK-NEXT: T: goto a; |
734 | // CHECK-NEXT: Preds (1): B4 |
735 | // CHECK-NEXT: Succs (1): B1 |
736 | // CHECK: [B0 (EXIT)] |
737 | // CHECK-NEXT: Preds (1): B1 |
738 | void goto_past_declaration2() { |
739 | { |
740 | int i; |
741 | goto a; |
742 | int j; |
743 | } |
744 | { |
745 | int k; |
746 | a: |
747 | k = 1; |
748 | } |
749 | } |
750 | |
751 | struct B { |
752 | ~B(); |
753 | }; |
754 | |
755 | // CHECK: [B4 (ENTRY)] |
756 | // CHECK-NEXT: Succs (1): B3 |
757 | // CHECK: [B1] |
758 | // CHECK-NEXT: 1: i |
759 | // CHECK-NEXT: 2: [B1.1]++ |
760 | // CHECK-NEXT: 3: [B2.2] (Lifetime ends) |
761 | // CHECK-NEXT: 4: [B3.1] (Lifetime ends) |
762 | // CHECK-NEXT: Succs (1): B0 |
763 | // CHECK: [B2] |
764 | // CHECK-NEXT: label: |
765 | // CHECK-NEXT: 1: (CXXConstructExpr, struct B) |
766 | // CHECK-NEXT: 2: B b; |
767 | // CHECK-NEXT: 3: [B2.2] (Lifetime ends) |
768 | // CHECK-NEXT: T: goto label; |
769 | // CHECK-NEXT: Preds (2): B3 B2 |
770 | // CHECK-NEXT: Succs (1): B2 |
771 | // CHECK: [B3] |
772 | // CHECK-NEXT: 1: int i; |
773 | // CHECK-NEXT: Preds (1): B4 |
774 | // CHECK-NEXT: Succs (1): B2 |
775 | // CHECK: [B0 (EXIT)] |
776 | // CHECK-NEXT: Preds (1): B1 |
777 | int backpatched_goto() { |
778 | int i; |
779 | label: |
780 | B b; |
781 | goto label; |
782 | i++; |
783 | } |
784 | |