1 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-scopes=true %s > %t 2>&1 |
2 | // RUN: FileCheck --input-file=%t %s |
3 | |
4 | class A { |
5 | public: |
6 | // CHECK: [B1 (ENTRY)] |
7 | // CHECK-NEXT: Succs (1): B0 |
8 | // CHECK: [B0 (EXIT)] |
9 | // CHECK-NEXT: Preds (1): B1 |
10 | A() {} |
11 | |
12 | // CHECK: [B1 (ENTRY)] |
13 | // CHECK-NEXT: Succs (1): B0 |
14 | // CHECK: [B0 (EXIT)] |
15 | // CHECK-NEXT: Preds (1): B1 |
16 | ~A() {} |
17 | |
18 | // CHECK: [B2 (ENTRY)] |
19 | // CHECK-NEXT: Succs (1): B1 |
20 | // CHECK: [B1] |
21 | // CHECK-NEXT: 1: 1 |
22 | // CHECK-NEXT: 2: return [B1.1]; |
23 | // CHECK-NEXT: Preds (1): B2 |
24 | // CHECK-NEXT: Succs (1): B0 |
25 | // CHECK: [B0 (EXIT)] |
26 | // CHECK-NEXT: Preds (1): B1 |
27 | operator int() const { return 1; } |
28 | }; |
29 | |
30 | int getX(); |
31 | extern const bool UV; |
32 | |
33 | // CHECK: [B2 (ENTRY)] |
34 | // CHECK-NEXT: Succs (1): B1 |
35 | // CHECK: [B1] |
36 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
37 | // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class A [2]) |
38 | // CHECK-NEXT: 3: A a[2]; |
39 | // CHECK-NEXT: 4: (CXXConstructExpr, [B1.5], class A [0]) |
40 | // CHECK-NEXT: 5: A b[0]; |
41 | // CHECK-NEXT: 6: [B1.3].~A() (Implicit destructor) |
42 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
43 | // CHECK-NEXT: Preds (1): B2 |
44 | // CHECK-NEXT: Succs (1): B0 |
45 | // CHECK: [B0 (EXIT)] |
46 | // CHECK-NEXT: Preds (1): B1 |
47 | void test_array() { |
48 | A a[2]; |
49 | A b[0]; |
50 | } |
51 | |
52 | // CHECK: [B2 (ENTRY)] |
53 | // CHECK-NEXT: Succs (1): B1 |
54 | // CHECK: [B1] |
55 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
56 | // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class A) |
57 | // CHECK-NEXT: 3: A a; |
58 | // CHECK-NEXT: 4: CFGScopeBegin(c) |
59 | // CHECK-NEXT: 5: (CXXConstructExpr, [B1.6], class A) |
60 | // CHECK-NEXT: 6: A c; |
61 | // CHECK-NEXT: 7: (CXXConstructExpr, [B1.8], class A) |
62 | // CHECK-NEXT: 8: A d; |
63 | // CHECK-NEXT: 9: [B1.8].~A() (Implicit destructor) |
64 | // CHECK-NEXT: 10: [B1.6].~A() (Implicit destructor) |
65 | // CHECK-NEXT: 11: CFGScopeEnd(c) |
66 | // CHECK-NEXT: 12: (CXXConstructExpr, [B1.13], class A) |
67 | // CHECK-NEXT: 13: A b; |
68 | // CHECK-NEXT: 14: [B1.13].~A() (Implicit destructor) |
69 | // CHECK-NEXT: 15: [B1.3].~A() (Implicit destructor) |
70 | // CHECK-NEXT: 16: CFGScopeEnd(a) |
71 | // CHECK-NEXT: Preds (1): B2 |
72 | // CHECK-NEXT: Succs (1): B0 |
73 | // CHECK: [B0 (EXIT)] |
74 | // CHECK-NEXT: Preds (1): B1 |
75 | void test_scope() { |
76 | A a; |
77 | { A c; |
78 | A d; |
79 | } |
80 | A b; |
81 | } |
82 | |
83 | // CHECK: [B4 (ENTRY)] |
84 | // CHECK-NEXT: Succs (1): B3 |
85 | // CHECK: [B1] |
86 | // CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
87 | // CHECK-NEXT: 2: A c; |
88 | // CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) |
89 | // CHECK-NEXT: 4: [B3.5].~A() (Implicit destructor) |
90 | // CHECK-NEXT: 5: [B3.3].~A() (Implicit destructor) |
91 | // CHECK-NEXT: 6: CFGScopeEnd(a) |
92 | // CHECK-NEXT: Preds (1): B3 |
93 | // CHECK-NEXT: Succs (1): B0 |
94 | // CHECK: [B2] |
95 | // CHECK-NEXT: 1: return; |
96 | // CHECK-NEXT: 2: [B3.5].~A() (Implicit destructor) |
97 | // CHECK-NEXT: 3: [B3.3].~A() (Implicit destructor) |
98 | // CHECK-NEXT: 4: CFGScopeEnd(a) |
99 | // CHECK-NEXT: Preds (1): B3 |
100 | // CHECK-NEXT: Succs (1): B0 |
101 | // CHECK: [B3] |
102 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
103 | // CHECK-NEXT: 2: (CXXConstructExpr, [B3.3], class A) |
104 | // CHECK-NEXT: 3: A a; |
105 | // CHECK-NEXT: 4: (CXXConstructExpr, [B3.5], class A) |
106 | // CHECK-NEXT: 5: A b; |
107 | // CHECK-NEXT: 6: UV |
108 | // CHECK-NEXT: 7: [B3.6] (ImplicitCastExpr, LValueToRValue, _Bool) |
109 | // CHECK-NEXT: T: if [B3.7] |
110 | // CHECK-NEXT: Preds (1): B4 |
111 | // CHECK-NEXT: Succs (2): B2 B1 |
112 | // CHECK: [B0 (EXIT)] |
113 | // CHECK-NEXT: Preds (2): B1 B2 |
114 | void test_return() { |
115 | A a; |
116 | A b; |
117 | if (UV) return; |
118 | A c; |
119 | } |
120 | |
121 | // CHECK: [B5 (ENTRY)] |
122 | // CHECK-NEXT: Succs (1): B4 |
123 | // CHECK: [B1] |
124 | // CHECK-NEXT: 1: [B4.8].~A() (Implicit destructor) |
125 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
126 | // CHECK-NEXT: 3: [B4.3].~A() (Implicit destructor) |
127 | // CHECK-NEXT: 4: CFGScopeEnd(a) |
128 | // CHECK-NEXT: Preds (2): B2 B3 |
129 | // CHECK-NEXT: Succs (1): B0 |
130 | // CHECK: [B2] |
131 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
132 | // CHECK-NEXT: 2: (CXXConstructExpr, [B2.3], class A) |
133 | // CHECK-NEXT: 3: A c; |
134 | // CHECK-NEXT: 4: [B2.3].~A() (Implicit destructor) |
135 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
136 | // CHECK-NEXT: Preds (1): B4 |
137 | // CHECK-NEXT: Succs (1): B1 |
138 | // CHECK: [B3] |
139 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
140 | // CHECK-NEXT: 2: (CXXConstructExpr, [B3.3], class A) |
141 | // CHECK-NEXT: 3: A c; |
142 | // CHECK-NEXT: 4: [B3.3].~A() (Implicit destructor) |
143 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
144 | // CHECK-NEXT: Preds (1): B4 |
145 | // CHECK-NEXT: Succs (1): B1 |
146 | // CHECK: [B4] |
147 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
148 | // CHECK-NEXT: 2: (CXXConstructExpr, [B4.3], class A) |
149 | // CHECK-NEXT: 3: A a; |
150 | // CHECK-NEXT: 4: CFGScopeBegin(b) |
151 | // CHECK-NEXT: 5: a |
152 | // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) |
153 | // CHECK-NEXT: 7: [B4.6] (CXXConstructExpr, [B4.8], class A) |
154 | // CHECK-NEXT: 8: A b = a; |
155 | // CHECK-NEXT: 9: b |
156 | // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, NoOp, const class A) |
157 | // CHECK-NEXT: 11: [B4.10].operator int |
158 | // CHECK-NEXT: 12: [B4.10] |
159 | // CHECK-NEXT: 13: [B4.12] (ImplicitCastExpr, UserDefinedConversion, int) |
160 | // CHECK-NEXT: 14: [B4.13] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
161 | // CHECK-NEXT: T: if [B4.14] |
162 | // CHECK-NEXT: Preds (1): B5 |
163 | // CHECK-NEXT: Succs (2): B3 B2 |
164 | // CHECK: [B0 (EXIT)] |
165 | // CHECK-NEXT: Preds (1): B1 |
166 | void test_if_implicit_scope() { |
167 | A a; |
168 | if (A b = a) |
169 | A c; |
170 | else A c; |
171 | } |
172 | |
173 | // CHECK: [B9 (ENTRY)] |
174 | // CHECK-NEXT: Succs (1): B8 |
175 | // CHECK: [B1] |
176 | // CHECK-NEXT: 1: [B8.8].~A() (Implicit destructor) |
177 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
178 | // CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], class A) |
179 | // CHECK-NEXT: 4: A e; |
180 | // CHECK-NEXT: 5: [B1.4].~A() (Implicit destructor) |
181 | // CHECK-NEXT: 6: [B8.3].~A() (Implicit destructor) |
182 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
183 | // CHECK-NEXT: Preds (2): B2 B5 |
184 | // CHECK-NEXT: Succs (1): B0 |
185 | // CHECK: [B2] |
186 | // CHECK-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
187 | // CHECK-NEXT: 2: A d; |
188 | // CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) |
189 | // CHECK-NEXT: 4: [B4.3].~A() (Implicit destructor) |
190 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
191 | // CHECK-NEXT: Preds (1): B4 |
192 | // CHECK-NEXT: Succs (1): B1 |
193 | // CHECK: [B3] |
194 | // CHECK-NEXT: 1: return; |
195 | // CHECK-NEXT: 2: [B4.3].~A() (Implicit destructor) |
196 | // CHECK-NEXT: 3: CFGScopeEnd(c) |
197 | // CHECK-NEXT: 4: [B8.8].~A() (Implicit destructor) |
198 | // CHECK-NEXT: 5: CFGScopeEnd(b) |
199 | // CHECK-NEXT: 6: [B8.3].~A() (Implicit destructor) |
200 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
201 | // CHECK-NEXT: Preds (1): B4 |
202 | // CHECK-NEXT: Succs (1): B0 |
203 | // CHECK: [B4] |
204 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
205 | // CHECK-NEXT: 2: (CXXConstructExpr, [B4.3], class A) |
206 | // CHECK-NEXT: 3: A c; |
207 | // CHECK-NEXT: 4: UV |
208 | // CHECK-NEXT: 5: [B4.4] (ImplicitCastExpr, LValueToRValue, _Bool) |
209 | // CHECK-NEXT: T: if [B4.5] |
210 | // CHECK-NEXT: Preds (1): B8 |
211 | // CHECK-NEXT: Succs (2): B3 B2 |
212 | // CHECK: [B5] |
213 | // CHECK-NEXT: 1: (CXXConstructExpr, [B5.2], class A) |
214 | // CHECK-NEXT: 2: A d; |
215 | // CHECK-NEXT: 3: [B5.2].~A() (Implicit destructor) |
216 | // CHECK-NEXT: 4: [B7.3].~A() (Implicit destructor) |
217 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
218 | // CHECK-NEXT: Preds (1): B7 |
219 | // CHECK-NEXT: Succs (1): B1 |
220 | // CHECK: [B6] |
221 | // CHECK-NEXT: 1: return; |
222 | // CHECK-NEXT: 2: [B7.3].~A() (Implicit destructor) |
223 | // CHECK-NEXT: 3: CFGScopeEnd(c) |
224 | // CHECK-NEXT: 4: [B8.8].~A() (Implicit destructor) |
225 | // CHECK-NEXT: 5: CFGScopeEnd(b) |
226 | // CHECK-NEXT: 6: [B8.3].~A() (Implicit destructor) |
227 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
228 | // CHECK-NEXT: Preds (1): B7 |
229 | // CHECK-NEXT: Succs (1): B0 |
230 | // CHECK: [B7] |
231 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
232 | // CHECK-NEXT: 2: (CXXConstructExpr, [B7.3], class A) |
233 | // CHECK-NEXT: 3: A c; |
234 | // CHECK-NEXT: 4: UV |
235 | // CHECK-NEXT: 5: [B7.4] (ImplicitCastExpr, LValueToRValue, _Bool) |
236 | // CHECK-NEXT: T: if [B7.5] |
237 | // CHECK-NEXT: Preds (1): B8 |
238 | // CHECK-NEXT: Succs (2): B6 B5 |
239 | // CHECK: [B8] |
240 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
241 | // CHECK-NEXT: 2: (CXXConstructExpr, [B8.3], class A) |
242 | // CHECK-NEXT: 3: A a; |
243 | // CHECK-NEXT: 4: CFGScopeBegin(b) |
244 | // CHECK-NEXT: 5: a |
245 | // CHECK-NEXT: 6: [B8.5] (ImplicitCastExpr, NoOp, const class A) |
246 | // CHECK-NEXT: 7: [B8.6] (CXXConstructExpr, [B8.8], class A) |
247 | // CHECK-NEXT: 8: A b = a; |
248 | // CHECK-NEXT: 9: b |
249 | // CHECK-NEXT: 10: [B8.9] (ImplicitCastExpr, NoOp, const class A) |
250 | // CHECK-NEXT: 11: [B8.10].operator int |
251 | // CHECK-NEXT: 12: [B8.10] |
252 | // CHECK-NEXT: 13: [B8.12] (ImplicitCastExpr, UserDefinedConversion, int) |
253 | // CHECK-NEXT: 14: [B8.13] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
254 | // CHECK-NEXT: T: if [B8.14] |
255 | // CHECK-NEXT: Preds (1): B9 |
256 | // CHECK-NEXT: Succs (2): B7 B4 |
257 | // CHECK: [B0 (EXIT)] |
258 | // CHECK-NEXT: Preds (3): B1 B3 B6 |
259 | void test_if_jumps() { |
260 | A a; |
261 | if (A b = a) { |
262 | A c; |
263 | if (UV) return; |
264 | A d; |
265 | } else { |
266 | A c; |
267 | if (UV) return; |
268 | A d; |
269 | } |
270 | A e; |
271 | } |
272 | |
273 | // CHECK: [B6 (ENTRY)] |
274 | // CHECK-NEXT: Succs (1): B5 |
275 | // CHECK: [B1] |
276 | // CHECK-NEXT: 1: [B4.5].~A() (Implicit destructor) |
277 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
278 | // CHECK-NEXT: 3: [B5.3].~A() (Implicit destructor) |
279 | // CHECK-NEXT: 4: CFGScopeEnd(a) |
280 | // CHECK-NEXT: Preds (1): B4 |
281 | // CHECK-NEXT: Succs (1): B0 |
282 | // CHECK: [B2] |
283 | // CHECK-NEXT: Preds (1): B3 |
284 | // CHECK-NEXT: Succs (1): B4 |
285 | // CHECK: [B3] |
286 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
287 | // CHECK-NEXT: 2: (CXXConstructExpr, [B3.3], class A) |
288 | // CHECK-NEXT: 3: A c; |
289 | // CHECK-NEXT: 4: [B3.3].~A() (Implicit destructor) |
290 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
291 | // CHECK-NEXT: 6: [B4.5].~A() (Implicit destructor) |
292 | // CHECK-NEXT: 7: CFGScopeEnd(b) |
293 | // CHECK-NEXT: Preds (1): B4 |
294 | // CHECK-NEXT: Succs (1): B2 |
295 | // CHECK: [B4] |
296 | // CHECK-NEXT: 1: CFGScopeBegin(b) |
297 | // CHECK-NEXT: 2: a |
298 | // CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, NoOp, const class A) |
299 | // CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, [B4.5], class A) |
300 | // CHECK-NEXT: 5: A b = a; |
301 | // CHECK-NEXT: 6: b |
302 | // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, NoOp, const class A) |
303 | // CHECK-NEXT: 8: [B4.7].operator int |
304 | // CHECK-NEXT: 9: [B4.7] |
305 | // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, UserDefinedConversion, int) |
306 | // CHECK-NEXT: 11: [B4.10] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
307 | // CHECK-NEXT: T: while [B4.11] |
308 | // CHECK-NEXT: Preds (2): B2 B5 |
309 | // CHECK-NEXT: Succs (2): B3 B1 |
310 | // CHECK: [B5] |
311 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
312 | // CHECK-NEXT: 2: (CXXConstructExpr, [B5.3], class A) |
313 | // CHECK-NEXT: 3: A a; |
314 | // CHECK-NEXT: Preds (1): B6 |
315 | // CHECK-NEXT: Succs (1): B4 |
316 | // CHECK: [B0 (EXIT)] |
317 | // CHECK-NEXT: Preds (1): B1 |
318 | void test_while_implicit_scope() { |
319 | A a; |
320 | while (A b = a) |
321 | A c; |
322 | } |
323 | |
324 | // CHECK: [B12 (ENTRY)] |
325 | // CHECK-NEXT: Succs (1): B11 |
326 | // CHECK: [B1] |
327 | // CHECK-NEXT: 1: [B10.5].~A() (Implicit destructor) |
328 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
329 | // CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], class A) |
330 | // CHECK-NEXT: 4: A e; |
331 | // CHECK-NEXT: 5: [B1.4].~A() (Implicit destructor) |
332 | // CHECK-NEXT: 6: [B11.3].~A() (Implicit destructor) |
333 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
334 | // CHECK-NEXT: Preds (2): B8 B10 |
335 | // CHECK-NEXT: Succs (1): B0 |
336 | // CHECK: [B2] |
337 | // CHECK-NEXT: Preds (2): B3 B6 |
338 | // CHECK-NEXT: Succs (1): B10 |
339 | // CHECK: [B3] |
340 | // CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
341 | // CHECK-NEXT: 2: A d; |
342 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
343 | // CHECK-NEXT: 4: [B9.3].~A() (Implicit destructor) |
344 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
345 | // CHECK-NEXT: 6: [B10.5].~A() (Implicit destructor) |
346 | // CHECK-NEXT: 7: CFGScopeEnd(b) |
347 | // CHECK-NEXT: Preds (1): B5 |
348 | // CHECK-NEXT: Succs (1): B2 |
349 | // CHECK: [B4] |
350 | // CHECK-NEXT: 1: return; |
351 | // CHECK-NEXT: 2: [B9.3].~A() (Implicit destructor) |
352 | // CHECK-NEXT: 3: CFGScopeEnd(c) |
353 | // CHECK-NEXT: 4: [B10.5].~A() (Implicit destructor) |
354 | // CHECK-NEXT: 5: CFGScopeEnd(b) |
355 | // CHECK-NEXT: 6: [B11.3].~A() (Implicit destructor) |
356 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
357 | // CHECK-NEXT: Preds (1): B5 |
358 | // CHECK-NEXT: Succs (1): B0 |
359 | // CHECK: [B5] |
360 | // CHECK-NEXT: 1: UV |
361 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
362 | // CHECK-NEXT: T: if [B5.2] |
363 | // CHECK-NEXT: Preds (1): B7 |
364 | // CHECK-NEXT: Succs (2): B4 B3 |
365 | // CHECK: [B6] |
366 | // CHECK-NEXT: 1: [B9.3].~A() (Implicit destructor) |
367 | // CHECK-NEXT: 2: CFGScopeEnd(c) |
368 | // CHECK-NEXT: 3: [B10.5].~A() (Implicit destructor) |
369 | // CHECK-NEXT: 4: CFGScopeEnd(b) |
370 | // CHECK-NEXT: T: continue; |
371 | // CHECK-NEXT: Preds (1): B7 |
372 | // CHECK-NEXT: Succs (1): B2 |
373 | // CHECK: [B7] |
374 | // CHECK-NEXT: 1: UV |
375 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
376 | // CHECK-NEXT: T: if [B7.2] |
377 | // CHECK-NEXT: Preds (1): B9 |
378 | // CHECK-NEXT: Succs (2): B6 B5 |
379 | // CHECK: [B8] |
380 | // CHECK-NEXT: 1: [B9.3].~A() (Implicit destructor) |
381 | // CHECK-NEXT: 2: CFGScopeEnd(c) |
382 | // CHECK-NEXT: T: break; |
383 | // CHECK-NEXT: Preds (1): B9 |
384 | // CHECK-NEXT: Succs (1): B1 |
385 | // CHECK: [B9] |
386 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
387 | // CHECK-NEXT: 2: (CXXConstructExpr, [B9.3], class A) |
388 | // CHECK-NEXT: 3: A c; |
389 | // CHECK-NEXT: 4: UV |
390 | // CHECK-NEXT: 5: [B9.4] (ImplicitCastExpr, LValueToRValue, _Bool) |
391 | // CHECK-NEXT: T: if [B9.5] |
392 | // CHECK-NEXT: Preds (1): B10 |
393 | // CHECK-NEXT: Succs (2): B8 B7 |
394 | // CHECK: [B10] |
395 | // CHECK-NEXT: 1: CFGScopeBegin(b) |
396 | // CHECK-NEXT: 2: a |
397 | // CHECK-NEXT: 3: [B10.2] (ImplicitCastExpr, NoOp, const class A) |
398 | // CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, [B10.5], class A) |
399 | // CHECK-NEXT: 5: A b = a; |
400 | // CHECK-NEXT: 6: b |
401 | // CHECK-NEXT: 7: [B10.6] (ImplicitCastExpr, NoOp, const class A) |
402 | // CHECK-NEXT: 8: [B10.7].operator int |
403 | // CHECK-NEXT: 9: [B10.7] |
404 | // CHECK-NEXT: 10: [B10.9] (ImplicitCastExpr, UserDefinedConversion, int) |
405 | // CHECK-NEXT: 11: [B10.10] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
406 | // CHECK-NEXT: T: while [B10.11] |
407 | // CHECK-NEXT: Preds (2): B2 B11 |
408 | // CHECK-NEXT: Succs (2): B9 B1 |
409 | // CHECK: [B11] |
410 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
411 | // CHECK-NEXT: 2: (CXXConstructExpr, [B11.3], class A) |
412 | // CHECK-NEXT: 3: A a; |
413 | // CHECK-NEXT: Preds (1): B12 |
414 | // CHECK-NEXT: Succs (1): B10 |
415 | // CHECK: [B0 (EXIT)] |
416 | // CHECK-NEXT: Preds (2): B1 B4 |
417 | void test_while_jumps() { |
418 | A a; |
419 | while (A b = a) { |
420 | A c; |
421 | if (UV) break; |
422 | if (UV) continue; |
423 | if (UV) return; |
424 | A d; |
425 | } |
426 | A e; |
427 | } |
428 | |
429 | // CHECK: [B12 (ENTRY)] |
430 | // CHECK-NEXT: Succs (1): B11 |
431 | // CHECK: [B1] |
432 | // CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
433 | // CHECK-NEXT: 2: A d; |
434 | // CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) |
435 | // CHECK-NEXT: 4: [B11.3].~A() (Implicit destructor) |
436 | // CHECK-NEXT: 5: CFGScopeEnd(a) |
437 | // CHECK-NEXT: Preds (2): B8 B2 |
438 | // CHECK-NEXT: Succs (1): B0 |
439 | // CHECK: [B2] |
440 | // CHECK-NEXT: 1: UV |
441 | // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
442 | // CHECK-NEXT: T: do ... while [B2.2] |
443 | // CHECK-NEXT: Preds (2): B3 B6 |
444 | // CHECK-NEXT: Succs (2): B10 B1 |
445 | // CHECK: [B3] |
446 | // CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
447 | // CHECK-NEXT: 2: A c; |
448 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
449 | // CHECK-NEXT: 4: [B9.3].~A() (Implicit destructor) |
450 | // CHECK-NEXT: 5: CFGScopeEnd(b) |
451 | // CHECK-NEXT: Preds (1): B5 |
452 | // CHECK-NEXT: Succs (1): B2 |
453 | // CHECK: [B4] |
454 | // CHECK-NEXT: 1: return; |
455 | // CHECK-NEXT: 2: [B9.3].~A() (Implicit destructor) |
456 | // CHECK-NEXT: 3: CFGScopeEnd(b) |
457 | // CHECK-NEXT: 4: [B11.3].~A() (Implicit destructor) |
458 | // CHECK-NEXT: 5: CFGScopeEnd(a) |
459 | // CHECK-NEXT: Preds (1): B5 |
460 | // CHECK-NEXT: Succs (1): B0 |
461 | // CHECK: [B5] |
462 | // CHECK-NEXT: 1: UV |
463 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
464 | // CHECK-NEXT: T: if [B5.2] |
465 | // CHECK-NEXT: Preds (1): B7 |
466 | // CHECK-NEXT: Succs (2): B4 B3 |
467 | // CHECK: [B6] |
468 | // CHECK-NEXT: 1: [B9.3].~A() (Implicit destructor) |
469 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
470 | // CHECK-NEXT: T: continue; |
471 | // CHECK-NEXT: Preds (1): B7 |
472 | // CHECK-NEXT: Succs (1): B2 |
473 | // CHECK: [B7] |
474 | // CHECK-NEXT: 1: UV |
475 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
476 | // CHECK-NEXT: T: if [B7.2] |
477 | // CHECK-NEXT: Preds (1): B9 |
478 | // CHECK-NEXT: Succs (2): B6 B5 |
479 | // CHECK: [B8] |
480 | // CHECK-NEXT: 1: [B9.3].~A() (Implicit destructor) |
481 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
482 | // CHECK-NEXT: T: break; |
483 | // CHECK-NEXT: Preds (1): B9 |
484 | // CHECK-NEXT: Succs (1): B1 |
485 | // CHECK: [B9] |
486 | // CHECK-NEXT: 1: CFGScopeBegin(b) |
487 | // CHECK-NEXT: 2: (CXXConstructExpr, [B9.3], class A) |
488 | // CHECK-NEXT: 3: A b; |
489 | // CHECK-NEXT: 4: UV |
490 | // CHECK-NEXT: 5: [B9.4] (ImplicitCastExpr, LValueToRValue, _Bool) |
491 | // CHECK-NEXT: T: if [B9.5] |
492 | // CHECK-NEXT: Preds (2): B10 B11 |
493 | // CHECK-NEXT: Succs (2): B8 B7 |
494 | // CHECK: [B10] |
495 | // CHECK-NEXT: Preds (1): B2 |
496 | // CHECK-NEXT: Succs (1): B9 |
497 | // CHECK: [B11] |
498 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
499 | // CHECK-NEXT: 2: (CXXConstructExpr, [B11.3], class A) |
500 | // CHECK-NEXT: 3: A a; |
501 | // CHECK-NEXT: Preds (1): B12 |
502 | // CHECK-NEXT: Succs (1): B9 |
503 | // CHECK: [B0 (EXIT)] |
504 | // CHECK-NEXT: Preds (2): B1 B4 |
505 | void test_do_jumps() { |
506 | A a; |
507 | do { |
508 | A b; |
509 | if (UV) break; |
510 | if (UV) continue; |
511 | if (UV) return; |
512 | A c; |
513 | } while (UV); |
514 | A d; |
515 | } |
516 | |
517 | // CHECK: [B6 (ENTRY)] |
518 | // CHECK-NEXT: Succs (1): B5 |
519 | // CHECK: [B1] |
520 | // CHECK-NEXT: 1: [B4.5].~A() (Implicit destructor) |
521 | // CHECK-NEXT: 2: CFGScopeEnd(b) |
522 | // CHECK-NEXT: 3: [B5.3].~A() (Implicit destructor) |
523 | // CHECK-NEXT: 4: CFGScopeEnd(a) |
524 | // CHECK-NEXT: Preds (1): B4 |
525 | // CHECK-NEXT: Succs (1): B0 |
526 | // CHECK: [B2] |
527 | // CHECK-NEXT: Preds (1): B3 |
528 | // CHECK-NEXT: Succs (1): B4 |
529 | // CHECK: [B3] |
530 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
531 | // CHECK-NEXT: 2: (CXXConstructExpr, [B3.3], class A) |
532 | // CHECK-NEXT: 3: A c; |
533 | // CHECK-NEXT: 4: [B3.3].~A() (Implicit destructor) |
534 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
535 | // CHECK-NEXT: 6: [B4.5].~A() (Implicit destructor) |
536 | // CHECK-NEXT: 7: CFGScopeEnd(b) |
537 | // CHECK-NEXT: Preds (1): B4 |
538 | // CHECK-NEXT: Succs (1): B2 |
539 | // CHECK: [B4] |
540 | // CHECK-NEXT: 1: CFGScopeBegin(b) |
541 | // CHECK-NEXT: 2: a |
542 | // CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, NoOp, const class A) |
543 | // CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, [B4.5], class A) |
544 | // CHECK-NEXT: 5: A b = a; |
545 | // CHECK-NEXT: 6: b |
546 | // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, NoOp, const class A) |
547 | // CHECK-NEXT: 8: [B4.7].operator int |
548 | // CHECK-NEXT: 9: [B4.7] |
549 | // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, UserDefinedConversion, int) |
550 | // CHECK-NEXT: 11: [B4.10] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
551 | // CHECK-NEXT: T: for (...; [B4.11]; ) |
552 | // CHECK-NEXT: Preds (2): B2 B5 |
553 | // CHECK-NEXT: Succs (2): B3 B1 |
554 | // CHECK: [B5] |
555 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
556 | // CHECK-NEXT: 2: (CXXConstructExpr, [B5.3], class A) |
557 | // CHECK-NEXT: 3: 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.5].~A() (Implicit destructor) |
571 | // CHECK-NEXT: 2: CFGScopeEnd(c) |
572 | // CHECK-NEXT: 3: [B11.6].~A() (Implicit destructor) |
573 | // CHECK-NEXT: 4: CFGScopeEnd(b) |
574 | // CHECK-NEXT: 5: (CXXConstructExpr, [B1.6], class A) |
575 | // CHECK-NEXT: 6: A f; |
576 | // CHECK-NEXT: 7: [B1.6].~A() (Implicit destructor) |
577 | // CHECK-NEXT: 8: [B11.3].~A() (Implicit destructor) |
578 | // CHECK-NEXT: 9: CFGScopeEnd(a) |
579 | // CHECK-NEXT: Preds (2): B8 B10 |
580 | // CHECK-NEXT: Succs (1): B0 |
581 | // CHECK: [B2] |
582 | // CHECK-NEXT: Preds (2): B3 B6 |
583 | // CHECK-NEXT: Succs (1): B10 |
584 | // CHECK: [B3] |
585 | // CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
586 | // CHECK-NEXT: 2: A e; |
587 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
588 | // CHECK-NEXT: 4: [B9.3].~A() (Implicit destructor) |
589 | // CHECK-NEXT: 5: CFGScopeEnd(d) |
590 | // CHECK-NEXT: 6: [B10.5].~A() (Implicit destructor) |
591 | // CHECK-NEXT: 7: CFGScopeEnd(c) |
592 | // CHECK-NEXT: Preds (1): B5 |
593 | // CHECK-NEXT: Succs (1): B2 |
594 | // CHECK: [B4] |
595 | // CHECK-NEXT: 1: return; |
596 | // CHECK-NEXT: 2: [B9.3].~A() (Implicit destructor) |
597 | // CHECK-NEXT: 3: CFGScopeEnd(d) |
598 | // CHECK-NEXT: 4: [B10.5].~A() (Implicit destructor) |
599 | // CHECK-NEXT: 5: CFGScopeEnd(c) |
600 | // CHECK-NEXT: 6: [B11.6].~A() (Implicit destructor) |
601 | // CHECK-NEXT: 7: CFGScopeEnd(b) |
602 | // CHECK-NEXT: 8: [B11.3].~A() (Implicit destructor) |
603 | // CHECK-NEXT: 9: CFGScopeEnd(a) |
604 | // CHECK-NEXT: Preds (1): B5 |
605 | // CHECK-NEXT: Succs (1): B0 |
606 | // CHECK: [B5] |
607 | // CHECK-NEXT: 1: UV |
608 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
609 | // CHECK-NEXT: T: if [B5.2] |
610 | // CHECK-NEXT: Preds (1): B7 |
611 | // CHECK-NEXT: Succs (2): B4 B3 |
612 | // CHECK: [B6] |
613 | // CHECK-NEXT: 1: [B9.3].~A() (Implicit destructor) |
614 | // CHECK-NEXT: 2: CFGScopeEnd(d) |
615 | // CHECK-NEXT: T: continue; |
616 | // CHECK-NEXT: Preds (1): B7 |
617 | // CHECK-NEXT: Succs (1): B2 |
618 | // CHECK: [B7] |
619 | // CHECK-NEXT: 1: UV |
620 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
621 | // CHECK-NEXT: T: if [B7.2] |
622 | // CHECK-NEXT: Preds (1): B9 |
623 | // CHECK-NEXT: Succs (2): B6 B5 |
624 | // CHECK: [B8] |
625 | // CHECK-NEXT: 1: [B9.3].~A() (Implicit destructor) |
626 | // CHECK-NEXT: 2: CFGScopeEnd(d) |
627 | // CHECK-NEXT: T: break; |
628 | // CHECK-NEXT: Preds (1): B9 |
629 | // CHECK-NEXT: Succs (1): B1 |
630 | // CHECK: [B9] |
631 | // CHECK-NEXT: 1: CFGScopeBegin(d) |
632 | // CHECK-NEXT: 2: (CXXConstructExpr, [B9.3], class A) |
633 | // CHECK-NEXT: 3: A d; |
634 | // CHECK-NEXT: 4: UV |
635 | // CHECK-NEXT: 5: [B9.4] (ImplicitCastExpr, LValueToRValue, _Bool) |
636 | // CHECK-NEXT: T: if [B9.5] |
637 | // CHECK-NEXT: Preds (1): B10 |
638 | // CHECK-NEXT: Succs (2): B8 B7 |
639 | // CHECK: [B10] |
640 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
641 | // CHECK-NEXT: 2: b |
642 | // CHECK-NEXT: 3: [B10.2] (ImplicitCastExpr, NoOp, const class A) |
643 | // CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, [B10.5], class A) |
644 | // CHECK-NEXT: 5: A c = b; |
645 | // CHECK-NEXT: 6: c |
646 | // CHECK-NEXT: 7: [B10.6] (ImplicitCastExpr, NoOp, const class A) |
647 | // CHECK-NEXT: 8: [B10.7].operator int |
648 | // CHECK-NEXT: 9: [B10.7] |
649 | // CHECK-NEXT: 10: [B10.9] (ImplicitCastExpr, UserDefinedConversion, int) |
650 | // CHECK-NEXT: 11: [B10.10] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
651 | // CHECK-NEXT: T: for (...; [B10.11]; ) |
652 | // CHECK-NEXT: Preds (2): B2 B11 |
653 | // CHECK-NEXT: Succs (2): B9 B1 |
654 | // CHECK: [B11] |
655 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
656 | // CHECK-NEXT: 2: (CXXConstructExpr, [B11.3], class A) |
657 | // CHECK-NEXT: 3: A a; |
658 | // CHECK-NEXT: 4: CFGScopeBegin(b) |
659 | // CHECK-NEXT: 5: (CXXConstructExpr, [B11.6], class A) |
660 | // CHECK-NEXT: 6: A b; |
661 | // CHECK-NEXT: Preds (1): B12 |
662 | // CHECK-NEXT: Succs (1): B10 |
663 | // CHECK: [B0 (EXIT)] |
664 | // CHECK-NEXT: Preds (2): B1 B4 |
665 | void test_for_jumps() { |
666 | A a; |
667 | for (A b; A c = b; ) { |
668 | A d; |
669 | if (UV) break; |
670 | if (UV) continue; |
671 | if (UV) return; |
672 | A e; |
673 | } |
674 | A f; |
675 | } |
676 | |
677 | // CHECK: [B8 (ENTRY)] |
678 | // CHECK-NEXT: Succs (1): B7 |
679 | // CHECK: [B1] |
680 | // CHECK-NEXT: l1: |
681 | // CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
682 | // CHECK-NEXT: 2: A c; |
683 | // CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) |
684 | // CHECK-NEXT: 4: [B6.5].~A() (Implicit destructor) |
685 | // CHECK-NEXT: 5: [B6.3].~A() (Implicit destructor) |
686 | // CHECK-NEXT: 6: [B7.3].~A() (Implicit destructor) |
687 | // CHECK-NEXT: 7: CFGScopeEnd(a) |
688 | // CHECK-NEXT: Preds (2): B2 B3 |
689 | // CHECK-NEXT: Succs (1): B0 |
690 | // CHECK: [B2] |
691 | // CHECK-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
692 | // CHECK-NEXT: 2: A b; |
693 | // CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) |
694 | // CHECK-NEXT: 4: [B6.8].~A() (Implicit destructor) |
695 | // CHECK-NEXT: 5: CFGScopeEnd(a) |
696 | // CHECK-NEXT: Preds (1): B4 |
697 | // CHECK-NEXT: Succs (1): B1 |
698 | // CHECK: [B3] |
699 | // CHECK-NEXT: 1: [B6.8].~A() (Implicit destructor) |
700 | // CHECK-NEXT: 2: CFGScopeEnd(a) |
701 | // CHECK-NEXT: T: goto l1; |
702 | // CHECK-NEXT: Preds (1): B4 |
703 | // CHECK-NEXT: Succs (1): B1 |
704 | // CHECK: [B4] |
705 | // CHECK-NEXT: 1: UV |
706 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
707 | // CHECK-NEXT: T: if [B4.2] |
708 | // CHECK-NEXT: Preds (1): B6 |
709 | // CHECK-NEXT: Succs (2): B3 B2 |
710 | // CHECK: [B5] |
711 | // CHECK-NEXT: 1: [B6.8].~A() (Implicit destructor) |
712 | // CHECK-NEXT: 2: [B6.5].~A() (Implicit destructor) |
713 | // CHECK-NEXT: 3: [B6.3].~A() (Implicit destructor) |
714 | // CHECK-NEXT: 4: CFGScopeEnd(cb) |
715 | // CHECK-NEXT: T: goto l0; |
716 | // CHECK-NEXT: Preds (1): B6 |
717 | // CHECK-NEXT: Succs (1): B6 |
718 | // CHECK: [B6] |
719 | // CHECK-NEXT: l0: |
720 | // CHECK-NEXT: 1: CFGScopeBegin(cb) |
721 | // CHECK-NEXT: 2: (CXXConstructExpr, [B6.3], class A) |
722 | // CHECK-NEXT: 3: A cb; |
723 | // CHECK-NEXT: 4: (CXXConstructExpr, [B6.5], class A) |
724 | // CHECK-NEXT: 5: A b; |
725 | // CHECK-NEXT: 6: CFGScopeBegin(a) |
726 | // CHECK-NEXT: 7: (CXXConstructExpr, [B6.8], class A) |
727 | // CHECK-NEXT: 8: A a; |
728 | // CHECK-NEXT: 9: UV |
729 | // CHECK-NEXT: 10: [B6.9] (ImplicitCastExpr, LValueToRValue, _Bool) |
730 | // CHECK-NEXT: T: if [B6.10] |
731 | // CHECK-NEXT: Preds (2): B7 B5 |
732 | // CHECK-NEXT: Succs (2): B5 B4 |
733 | // CHECK: [B7] |
734 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
735 | // CHECK-NEXT: 2: (CXXConstructExpr, [B7.3], class A) |
736 | // CHECK-NEXT: 3: A a; |
737 | // CHECK-NEXT: Preds (1): B8 |
738 | // CHECK-NEXT: Succs (1): B6 |
739 | // CHECK: [B0 (EXIT)] |
740 | // CHECK-NEXT: Preds (1): B1 |
741 | void test_goto() { |
742 | A a; |
743 | l0: |
744 | A cb; |
745 | A b; |
746 | { A a; |
747 | if (UV) goto l0; |
748 | if (UV) goto l1; |
749 | A b; |
750 | } |
751 | l1: |
752 | A c; |
753 | } |
754 | |
755 | // CHECK: [B7 (ENTRY)] |
756 | // CHECK-NEXT: Succs (1): B6 |
757 | // CHECK: [B1] |
758 | // CHECK-NEXT: 1: CFGScopeEnd(i) |
759 | // CHECK-NEXT: 2: CFGScopeBegin(unused2) |
760 | // CHECK-NEXT: 3: int unused2; |
761 | // CHECK-NEXT: 4: CFGScopeEnd(unused2) |
762 | // CHECK-NEXT: Preds (2): B4 B5 |
763 | // CHECK-NEXT: Succs (1): B0 |
764 | // CHECK: [B2] |
765 | // CHECK-NEXT: 1: i |
766 | // CHECK-NEXT: 2: ++[B2.1] |
767 | // CHECK-NEXT: Preds (1): B3 |
768 | // CHECK-NEXT: Succs (1): B5 |
769 | // CHECK: [B3] |
770 | // CHECK-NEXT: 1: CFGScopeEnd(unused1) |
771 | // CHECK-NEXT: Succs (1): B2 |
772 | // CHECK: [B4] |
773 | // CHECK-NEXT: 1: CFGScopeBegin(unused1) |
774 | // CHECK-NEXT: 2: int unused1; |
775 | // CHECK-NEXT: 3: CFGScopeEnd(unused1) |
776 | // CHECK-NEXT: T: break; |
777 | // CHECK-NEXT: Preds (1): B5 |
778 | // CHECK-NEXT: Succs (1): B1 |
779 | // CHECK: [B5] |
780 | // CHECK-NEXT: 1: i |
781 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, int) |
782 | // CHECK-NEXT: 3: 3 |
783 | // CHECK-NEXT: 4: [B5.2] < [B5.3] |
784 | // CHECK-NEXT: T: for (...; [B5.4]; ...) |
785 | // CHECK-NEXT: Preds (2): B2 B6 |
786 | // CHECK-NEXT: Succs (2): B4 B1 |
787 | // CHECK: [B6] |
788 | // CHECK-NEXT: 1: CFGScopeBegin(i) |
789 | // CHECK-NEXT: 2: 0 |
790 | // CHECK-NEXT: 3: int i = 0; |
791 | // CHECK-NEXT: Preds (1): B7 |
792 | // CHECK-NEXT: Succs (1): B5 |
793 | // CHECK: [B0 (EXIT)] |
794 | // CHECK-NEXT: Preds (1): B1 |
795 | void test_for_compound_and_break() { |
796 | for (int i = 0; i < 3; ++i) { |
797 | { |
798 | int unused1; |
799 | break; |
800 | } |
801 | } |
802 | { |
803 | int unused2; |
804 | } |
805 | } |
806 | |
807 | // CHECK: [B6 (ENTRY)] |
808 | // CHECK-NEXT: Succs (1): B5 |
809 | // CHECK: [B1] |
810 | // CHECK-NEXT: 1: CFGScopeEnd(__end1) |
811 | // CHECK-NEXT: 2: CFGScopeEnd(__begin1) |
812 | // CHECK-NEXT: 3: CFGScopeEnd(__range1) |
813 | // CHECK-NEXT: 4: [B5.3].~A() (Implicit destructor) |
814 | // CHECK-NEXT: 5: CFGScopeEnd(a) |
815 | // CHECK-NEXT: Preds (1): B2 |
816 | // CHECK-NEXT: Succs (1): B0 |
817 | // CHECK: [B2] |
818 | // CHECK-NEXT: 1: __begin1 |
819 | // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, class A *) |
820 | // CHECK-NEXT: 3: __end1 |
821 | // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, class A *) |
822 | // CHECK-NEXT: 5: [B2.2] != [B2.4] |
823 | // CHECK-NEXT: T: for (auto &i : [B5.4]) |
824 | // CHECK: [B4.11]; |
825 | // CHECK: Preds (2): B3 B5 |
826 | // CHECK-NEXT: Succs (2): B4 B1 |
827 | // CHECK: [B3] |
828 | // CHECK-NEXT: 1: __begin1 |
829 | // CHECK-NEXT: 2: ++[B3.1] |
830 | // CHECK-NEXT: Preds (1): B4 |
831 | // CHECK-NEXT: Succs (1): B2 |
832 | // CHECK: [B4] |
833 | // CHECK-NEXT: 1: CFGScopeBegin(i) |
834 | // CHECK-NEXT: 2: __begin1 |
835 | // CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, LValueToRValue, class A *) |
836 | // CHECK-NEXT: 4: *[B4.3] |
837 | // CHECK-NEXT: 5: auto &i = *__begin1; |
838 | // CHECK-NEXT: 6: operator= |
839 | // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, FunctionToPointerDecay, class A &(*)(const class A &) |
840 | // CHECK-NEXT: 8: i |
841 | // CHECK-NEXT: 9: b |
842 | // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, NoOp, const class A) |
843 | // CHECK-NEXT: 11: [B4.8] = [B4.10] (OperatorCall) |
844 | // CHECK-NEXT: 12: CFGScopeEnd(i) |
845 | // CHECK-NEXT: Preds (1): B2 |
846 | // CHECK-NEXT: Succs (1): B3 |
847 | // CHECK: [B5] |
848 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
849 | // CHECK-NEXT: 2: (CXXConstructExpr, [B5.3], class A [10]) |
850 | // CHECK-NEXT: 3: A a[10]; |
851 | // CHECK-NEXT: 4: a |
852 | // CHECK-NEXT: 5: auto &&__range1 = a; |
853 | // CHECK-NEXT: 6: CFGScopeBegin(__end1) |
854 | // CHECK-NEXT: 7: __range1 |
855 | // CHECK-NEXT: 8: [B5.7] (ImplicitCastExpr, ArrayToPointerDecay, class A *) |
856 | // CHECK-NEXT: 9: 10 |
857 | // CHECK-NEXT: 10: [B5.8] + [B5.9] |
858 | // CHECK-NEXT: 11: auto __end1 = __range1 + 10 |
859 | // CHECK-NEXT: 12: __range1 |
860 | // CHECK-NEXT: 13: [B5.12] (ImplicitCastExpr, ArrayToPointerDecay, class A *) |
861 | // CHECK-NEXT: 14: auto __begin1 = __range1; |
862 | // CHECK-NEXT: Preds (1): B6 |
863 | // CHECK-NEXT: Succs (1): B2 |
864 | // CHECK: [B0 (EXIT)] |
865 | // CHECK-NEXT: Preds (1): B1 |
866 | void test_range_for(A &b) { |
867 | A a[10]; |
868 | for (auto &i : a) |
869 | i = b; |
870 | } |
871 | |
872 | // CHECK: [B8 (ENTRY)] |
873 | // CHECK-NEXT: Succs (1): B2 |
874 | // CHECK: [B1] |
875 | // CHECK-NEXT: 1: CFGScopeEnd(i) |
876 | // CHECK-NEXT: 2: 1 |
877 | // CHECK-NEXT: 3: int k = 1; |
878 | // CHECK-NEXT: 4: CFGScopeEnd(c) |
879 | // CHECK-NEXT: Preds (3): B3 B5 B6 |
880 | // CHECK-NEXT: Succs (1): B0 |
881 | // CHECK: [B2] |
882 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
883 | // CHECK-NEXT: 2: '1' |
884 | // CHECK-NEXT: 3: char c = '1'; |
885 | // CHECK-NEXT: 4: CFGScopeBegin(i) |
886 | // CHECK-NEXT: 5: getX |
887 | // CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void)) |
888 | // CHECK-NEXT: 7: [B2.6]() |
889 | // CHECK-NEXT: 8: int i = getX(); |
890 | // CHECK-NEXT: 9: i |
891 | // CHECK-NEXT: 10: [B2.9] (ImplicitCastExpr, LValueToRValue, int) |
892 | // CHECK-NEXT: T: switch [B2.10] |
893 | // CHECK-NEXT: Preds (1): B8 |
894 | // CHECK-NEXT: Succs (5): B4 B5 B6 B7 B3 |
895 | // CHECK: [B3] |
896 | // CHECK-NEXT: default: |
897 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
898 | // CHECK-NEXT: 2: 0 |
899 | // CHECK-NEXT: 3: int a = 0; |
900 | // CHECK-NEXT: 4: i |
901 | // CHECK-NEXT: 5: ++[B3.4] |
902 | // CHECK-NEXT: 6: CFGScopeEnd(a) |
903 | // CHECK-NEXT: Preds (2): B4 B2 |
904 | // CHECK-NEXT: Succs (1): B1 |
905 | // CHECK: [B4] |
906 | // CHECK-NEXT: case 3: |
907 | // CHECK-NEXT: 1: '2' |
908 | // CHECK-NEXT: 2: c |
909 | // CHECK-NEXT: 3: [B4.2] = [B4.1] |
910 | // CHECK-NEXT: Preds (1): B2 |
911 | // CHECK-NEXT: Succs (1): B3 |
912 | // CHECK: [B5] |
913 | // CHECK-NEXT: case 2: |
914 | // CHECK-NEXT: 1: '2' |
915 | // CHECK-NEXT: 2: c |
916 | // CHECK-NEXT: 3: [B5.2] = [B5.1] |
917 | // CHECK-NEXT: T: break; |
918 | // CHECK-NEXT: Preds (1): B2 |
919 | // CHECK-NEXT: Succs (1): B1 |
920 | // CHECK: [B6] |
921 | // CHECK-NEXT: case 1: |
922 | // CHECK-NEXT: 1: '3' |
923 | // CHECK-NEXT: 2: c |
924 | // CHECK-NEXT: 3: [B6.2] = [B6.1] |
925 | // CHECK-NEXT: T: break; |
926 | // CHECK-NEXT: Preds (2): B2 B7 |
927 | // CHECK-NEXT: Succs (1): B1 |
928 | // CHECK: [B7] |
929 | // CHECK-NEXT: case 0: |
930 | // CHECK-NEXT: 1: '2' |
931 | // CHECK-NEXT: 2: c |
932 | // CHECK-NEXT: 3: [B7.2] = [B7.1] |
933 | // CHECK-NEXT: Preds (1): B2 |
934 | // CHECK-NEXT: Succs (1): B6 |
935 | // CHECK: [B0 (EXIT)] |
936 | // CHECK-NEXT: Preds (1): B1 |
937 | void test_switch_with_compound_with_default() { |
938 | char c = '1'; |
939 | switch (int i = getX()) { |
940 | case 0: |
941 | c = '2'; |
942 | case 1: |
943 | c = '3'; |
944 | break; |
945 | case 2: { |
946 | c = '2'; |
947 | break; |
948 | } |
949 | case 3: |
950 | c = '2'; |
951 | default: { |
952 | int a = 0; |
953 | ++i; |
954 | } |
955 | } |
956 | int k = 1; |
957 | } |
958 | |
959 | // CHECK: [B6 (ENTRY)] |
960 | // CHECK-NEXT: Succs (1): B2 |
961 | // CHECK: [B1] |
962 | // CHECK-NEXT: 1: CFGScopeEnd(i) |
963 | // CHECK-NEXT: 2: 3 |
964 | // CHECK-NEXT: 3: int k = 3; |
965 | // CHECK-NEXT: 4: CFGScopeEnd(c) |
966 | // CHECK-NEXT: Preds (3): B3 B4 B2 |
967 | // CHECK-NEXT: Succs (1): B0 |
968 | // CHECK: [B2] |
969 | // CHECK-NEXT: 1: CFGScopeBegin(c) |
970 | // CHECK-NEXT: 2: '1' |
971 | // CHECK-NEXT: 3: char c = '1'; |
972 | // CHECK-NEXT: 4: CFGScopeBegin(i) |
973 | // CHECK-NEXT: 5: getX |
974 | // CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void)) |
975 | // CHECK-NEXT: 7: [B2.6]() |
976 | // CHECK-NEXT: 8: int i = getX(); |
977 | // CHECK-NEXT: 9: i |
978 | // CHECK-NEXT: 10: [B2.9] (ImplicitCastExpr, LValueToRValue, int) |
979 | // CHECK-NEXT: T: switch [B2.10] |
980 | // CHECK-NEXT: Preds (1): B6 |
981 | // CHECK-NEXT: Succs (4): B3 B4 B5 B1 |
982 | // CHECK: [B3] |
983 | // CHECK-NEXT: case 2: |
984 | // CHECK-NEXT: 1: '3' |
985 | // CHECK-NEXT: 2: c |
986 | // CHECK-NEXT: 3: [B3.2] = [B3.1] |
987 | // CHECK-NEXT: T: break; |
988 | // CHECK-NEXT: Preds (1): B2 |
989 | // CHECK-NEXT: Succs (1): B1 |
990 | // CHECK: [B4] |
991 | // CHECK-NEXT: case 1: |
992 | // CHECK-NEXT: 1: '1' |
993 | // CHECK-NEXT: 2: c |
994 | // CHECK-NEXT: 3: [B4.2] = [B4.1] |
995 | // CHECK-NEXT: T: break; |
996 | // CHECK-NEXT: Preds (2): B2 B5 |
997 | // CHECK-NEXT: Succs (1): B1 |
998 | // CHECK: [B5] |
999 | // CHECK-NEXT: case 0: |
1000 | // CHECK-NEXT: 1: '2' |
1001 | // CHECK-NEXT: 2: c |
1002 | // CHECK-NEXT: 3: [B5.2] = [B5.1] |
1003 | // CHECK-NEXT: Preds (1): B2 |
1004 | // CHECK-NEXT: Succs (1): B4 |
1005 | // CHECK: [B0 (EXIT)] |
1006 | // CHECK-NEXT: Preds (1): B1 |
1007 | int test_switch_with_compound_without_default() { |
1008 | char c = '1'; |
1009 | switch (int i = getX()) { |
1010 | case 0: |
1011 | c = '2'; |
1012 | case 1: |
1013 | c = '1'; |
1014 | break; |
1015 | case 2: |
1016 | c = '3'; |
1017 | break; |
1018 | } |
1019 | int k = 3; |
1020 | } |
1021 | |
1022 | // CHECK: [B5 (ENTRY)] |
1023 | // CHECK-NEXT: Succs (1): B2 |
1024 | // CHECK: [B1] |
1025 | // CHECK-NEXT: 1: CFGScopeEnd(i) |
1026 | // CHECK-NEXT: 2: 1 |
1027 | // CHECK-NEXT: 3: int k = 1; |
1028 | // CHECK-NEXT: 4: CFGScopeEnd(s) |
1029 | // CHECK-NEXT: Preds (1): B3 |
1030 | // CHECK-NEXT: Succs (1): B0 |
1031 | // CHECK: [B2] |
1032 | // CHECK-NEXT: 1: CFGScopeBegin(s) |
1033 | // CHECK-NEXT: 2: '1' |
1034 | // CHECK-NEXT: 3: char s = '1'; |
1035 | // CHECK-NEXT: 4: CFGScopeBegin(i) |
1036 | // CHECK-NEXT: 5: getX |
1037 | // CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void)) |
1038 | // CHECK-NEXT: 7: [B2.6]() |
1039 | // CHECK-NEXT: 8: int i = getX(); |
1040 | // CHECK-NEXT: 9: i |
1041 | // CHECK-NEXT: 10: [B2.9] (ImplicitCastExpr, LValueToRValue, int) |
1042 | // CHECK-NEXT: T: switch [B2.10] |
1043 | // CHECK-NEXT: Preds (1): B5 |
1044 | // CHECK-NEXT: Succs (2): B4 B3 |
1045 | // CHECK: [B3] |
1046 | // CHECK-NEXT: default: |
1047 | // CHECK-NEXT: 1: CFGScopeBegin(a) |
1048 | // CHECK-NEXT: 2: 0 |
1049 | // CHECK-NEXT: 3: int a = 0; |
1050 | // CHECK-NEXT: 4: i |
1051 | // CHECK-NEXT: 5: ++[B3.4] |
1052 | // CHECK-NEXT: 6: CFGScopeEnd(a) |
1053 | // CHECK-NEXT: Preds (2): B4 B2 |
1054 | // CHECK-NEXT: Succs (1): B1 |
1055 | // CHECK: [B4] |
1056 | // CHECK-NEXT: case 0: |
1057 | // CHECK-NEXT: Preds (1): B2 |
1058 | // CHECK-NEXT: Succs (1): B3 |
1059 | // CHECK: [B0 (EXIT)] |
1060 | // CHECK-NEXT: Preds (1): B1 |
1061 | void test_without_compound() { |
1062 | char s = '1'; |
1063 | switch (int i = getX()) |
1064 | case 0: |
1065 | default: { |
1066 | int a = 0; |
1067 | ++i; |
1068 | } |
1069 | int k = 1; |
1070 | } |
1071 | |
1072 | // CHECK: [B12 (ENTRY)] |
1073 | // CHECK-NEXT: Succs (1): B11 |
1074 | // CHECK: [B1] |
1075 | // CHECK-NEXT: 1: CFGScopeEnd(i) |
1076 | // CHECK-NEXT: Preds (2): B4 B10 |
1077 | // CHECK-NEXT: Succs (1): B0 |
1078 | // CHECK: [B2] |
1079 | // CHECK-NEXT: 1: i |
1080 | // CHECK-NEXT: 2: ++[B2.1] |
1081 | // CHECK-NEXT: Preds (2): B3 B7 |
1082 | // CHECK-NEXT: Succs (1): B10 |
1083 | // CHECK: [B3] |
1084 | // CHECK-NEXT: 1: CFGScopeEnd(z) |
1085 | // CHECK-NEXT: Succs (1): B2 |
1086 | // CHECK: [B4] |
1087 | // CHECK-NEXT: 1: CFGScopeBegin(z) |
1088 | // CHECK-NEXT: 2: 5 |
1089 | // CHECK-NEXT: 3: int z = 5; |
1090 | // CHECK-NEXT: 4: CFGScopeEnd(z) |
1091 | // CHECK-NEXT: T: break; |
1092 | // CHECK-NEXT: Preds (2): B6 B8 |
1093 | // CHECK-NEXT: Succs (1): B1 |
1094 | // CHECK: [B5] |
1095 | // CHECK-NEXT: 1: x |
1096 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, int) |
1097 | // CHECK-NEXT: T: switch [B5.2] |
1098 | // CHECK-NEXT: Preds (1): B10 |
1099 | // CHECK-NEXT: Succs (4): B7 B8 B9 B6 |
1100 | // CHECK: [B6] |
1101 | // CHECK-NEXT: default: |
1102 | // CHECK-NEXT: 1: 3 |
1103 | // CHECK-NEXT: 2: y |
1104 | // CHECK-NEXT: 3: [B6.2] = [B6.1] |
1105 | // CHECK-NEXT: Preds (1): B5 |
1106 | // CHECK-NEXT: Succs (1): B4 |
1107 | // CHECK: [B7] |
1108 | // CHECK-NEXT: case 2: |
1109 | // CHECK-NEXT: 1: 4 |
1110 | // CHECK-NEXT: 2: y |
1111 | // CHECK-NEXT: 3: [B7.2] = [B7.1] |
1112 | // CHECK-NEXT: T: continue; |
1113 | // CHECK-NEXT: Preds (1): B5 |
1114 | // CHECK-NEXT: Succs (1): B2 |
1115 | // CHECK: [B8] |
1116 | // CHECK-NEXT: case 1: |
1117 | // CHECK-NEXT: 1: 2 |
1118 | // CHECK-NEXT: 2: y |
1119 | // CHECK-NEXT: 3: [B8.2] = [B8.1] |
1120 | // CHECK-NEXT: T: break; |
1121 | // CHECK-NEXT: Preds (2): B5 B9 |
1122 | // CHECK-NEXT: Succs (1): B4 |
1123 | // CHECK: [B9] |
1124 | // CHECK-NEXT: case 0: |
1125 | // CHECK-NEXT: 1: 1 |
1126 | // CHECK-NEXT: 2: y |
1127 | // CHECK-NEXT: 3: [B9.2] = [B9.1] |
1128 | // CHECK-NEXT: Preds (1): B5 |
1129 | // CHECK-NEXT: Succs (1): B8 |
1130 | // CHECK: [B10] |
1131 | // CHECK-NEXT: 1: i |
1132 | // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, LValueToRValue, int) |
1133 | // CHECK-NEXT: 3: 1000 |
1134 | // CHECK-NEXT: 4: [B10.2] < [B10.3] |
1135 | // CHECK-NEXT: T: for (...; [B10.4]; ...) |
1136 | // CHECK-NEXT: Preds (2): B2 B11 |
1137 | // CHECK-NEXT: Succs (2): B5 B1 |
1138 | // CHECK: [B11] |
1139 | // CHECK-NEXT: 1: CFGScopeBegin(i) |
1140 | // CHECK-NEXT: 2: int i; |
1141 | // CHECK-NEXT: 3: int x; |
1142 | // CHECK-NEXT: 4: int y; |
1143 | // CHECK-NEXT: 5: 0 |
1144 | // CHECK-NEXT: 6: i |
1145 | // CHECK-NEXT: 7: [B11.6] = [B11.5] |
1146 | // CHECK-NEXT: Preds (1): B12 |
1147 | // CHECK-NEXT: Succs (1): B10 |
1148 | // CHECK: [B0 (EXIT)] |
1149 | // CHECK-NEXT: Preds (1): B1 |
1150 | void test_for_switch_in_for() { |
1151 | int i, x, y; |
1152 | for (i = 0; i < 1000; ++i) { |
1153 | switch (x) { |
1154 | case 0: |
1155 | y = 1; |
1156 | case 1: |
1157 | y = 2; |
1158 | break; // break from switch |
1159 | case 2: |
1160 | y = 4; |
1161 | continue; // continue in loop |
1162 | default: |
1163 | y = 3; |
1164 | } |
1165 | { |
1166 | int z = 5; |
1167 | break; // break from loop |
1168 | } |
1169 | } |
1170 | } |
1171 | |