1 | // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-loopexit=true %s > %t 2>&1 |
2 | // RUN: FileCheck --input-file=%t %s |
3 | |
4 | // CHECK: [B6 (ENTRY)] |
5 | // CHECK-NEXT: Succs (1): B5 |
6 | |
7 | // CHECK: [B1] |
8 | // CHECK-NEXT: 1: ForStmt (LoopExit) |
9 | // CHECK-NEXT: 2: return; |
10 | // CHECK-NEXT: Preds (1): B4 |
11 | // CHECK-NEXT: Succs (1): B0 |
12 | |
13 | // CHECK: [B2] |
14 | // CHECK-NEXT: 1: i |
15 | // CHECK-NEXT: 2: [B2.1]++ |
16 | // CHECK-NEXT: Preds (1): B3 |
17 | // CHECK-NEXT: Succs (1): B4 |
18 | |
19 | // CHECK: [B3] |
20 | // CHECK-NEXT: 1: i |
21 | // CHECK-NEXT: 2: [B3.1]++ |
22 | // CHECK-NEXT: Preds (1): B4 |
23 | // CHECK-NEXT: Succs (1): B2 |
24 | |
25 | // CHECK: [B4] |
26 | // CHECK-NEXT: 1: i |
27 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int) |
28 | // CHECK-NEXT: 3: 12 |
29 | // CHECK-NEXT: 4: [B4.2] < [B4.3] |
30 | // CHECK-NEXT: T: for (...; [B4.4]; ...) |
31 | // CHECK-NEXT: Preds (2): B2 B5 |
32 | // CHECK-NEXT: Succs (2): B3 B1 |
33 | |
34 | // CHECK: [B5] |
35 | // CHECK-NEXT: 1: 0 |
36 | // CHECK-NEXT: 2: int i = 0; |
37 | // CHECK-NEXT: Preds (1): B6 |
38 | // CHECK-NEXT: Succs (1): B4 |
39 | |
40 | // CHECK: [B0 (EXIT)] |
41 | // CHECK-NEXT: Preds (1): B1 |
42 | void check_forloop1() { |
43 | for (int i = 0; i < 12; i++) { |
44 | i++; |
45 | } |
46 | return; |
47 | } |
48 | |
49 | // CHECK: [B4 (ENTRY)] |
50 | // CHECK-NEXT: Succs (1): B3 |
51 | |
52 | // CHECK: [B1] |
53 | // CHECK-NEXT: 1: ForStmt (LoopExit) |
54 | // CHECK-NEXT: Succs (1): B0 |
55 | |
56 | // CHECK: [B2] |
57 | // CHECK-NEXT: Preds (1): B3 |
58 | // CHECK-NEXT: Succs (1): B3 |
59 | |
60 | // CHECK: [B3] |
61 | // CHECK-NEXT: T: for (; ; ) |
62 | // CHECK-NEXT: Preds (2): B2 B4 |
63 | // CHECK-NEXT: Succs (2): B2 NULL |
64 | |
65 | // CHECK: [B0 (EXIT)] |
66 | // CHECK-NEXT: Preds (1): B1 |
67 | void check_forloop2() { |
68 | for (;;) |
69 | ; |
70 | } |
71 | |
72 | // CHECK: [B5 (ENTRY)] |
73 | // CHECK-NEXT: Succs (1): B4 |
74 | |
75 | // CHECK: [B1] |
76 | // CHECK-NEXT: 1: WhileStmt (LoopExit) |
77 | // CHECK-NEXT: Succs (1): B0 |
78 | |
79 | // CHECK: [B2] |
80 | // CHECK-NEXT: Preds (1): B3 |
81 | // CHECK-NEXT: Succs (1): B4 |
82 | |
83 | // CHECK: [B3] |
84 | // CHECK-NEXT: 1: int i; |
85 | // CHECK-NEXT: Preds (1): B4 |
86 | // CHECK-NEXT: Succs (1): B2 |
87 | |
88 | // CHECK: [B4] |
89 | // CHECK-NEXT: 1: true |
90 | // CHECK-NEXT: T: while [B4.1] |
91 | // CHECK-NEXT: Preds (2): B2 B5 |
92 | // CHECK-NEXT: Succs (2): B3 NULL |
93 | |
94 | // CHECK: [B0 (EXIT)] |
95 | // CHECK-NEXT: Preds (1): B1 |
96 | void check_while1() { |
97 | while (true) { |
98 | int i; |
99 | } |
100 | } |
101 | |
102 | // CHECK: [B5 (ENTRY)] |
103 | // CHECK-NEXT: Succs (1): B4 |
104 | |
105 | // CHECK: [B1] |
106 | // CHECK-NEXT: 1: WhileStmt (LoopExit) |
107 | // CHECK-NEXT: 2: 2 |
108 | // CHECK-NEXT: 3: int k = 2; |
109 | // CHECK-NEXT: 4: return; |
110 | // CHECK-NEXT: Preds (1): B3 |
111 | // CHECK-NEXT: Succs (1): B0 |
112 | |
113 | // CHECK: [B2] |
114 | // CHECK-NEXT: Preds (1): B3 |
115 | // CHECK-NEXT: Succs (1): B3 |
116 | |
117 | // CHECK: [B3] |
118 | // CHECK-NEXT: 1: l |
119 | // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, LValueToRValue, int) |
120 | // CHECK-NEXT: 3: 42 |
121 | // CHECK-NEXT: 4: [B3.2] < [B3.3] |
122 | // CHECK-NEXT: T: while [B3.4] |
123 | // CHECK-NEXT: Preds (2): B2 B4 |
124 | // CHECK-NEXT: Succs (2): B2 B1 |
125 | |
126 | // CHECK: [B4] |
127 | // CHECK-NEXT: 1: int l; |
128 | // CHECK-NEXT: Preds (1): B5 |
129 | // CHECK-NEXT: Succs (1): B3 |
130 | |
131 | // CHECK: [B0 (EXIT)] |
132 | // CHECK-NEXT: Preds (1): B1 |
133 | void check_while2() { |
134 | int l; |
135 | while (l < 42) |
136 | ; |
137 | int k = 2; |
138 | return; |
139 | } |
140 | |
141 | // CHECK: [B4 (ENTRY)] |
142 | // CHECK-NEXT: Succs (1): B3 |
143 | |
144 | // CHECK: [B1] |
145 | // CHECK-NEXT: 1: WhileStmt (LoopExit) |
146 | // CHECK-NEXT: Preds (1): B3 |
147 | // CHECK-NEXT: Succs (1): B0 |
148 | |
149 | // CHECK: [B2] |
150 | // CHECK-NEXT: Succs (1): B3 |
151 | |
152 | // CHECK: [B3] |
153 | // CHECK-NEXT: 1: false |
154 | // CHECK-NEXT: T: while [B3.1] |
155 | // CHECK-NEXT: Preds (2): B2 B4 |
156 | // CHECK-NEXT: Succs (2): NULL B1 |
157 | |
158 | // CHECK: [B0 (EXIT)] |
159 | // CHECK-NEXT: Preds (1): B1 |
160 | void check_while3() { |
161 | while (false) { |
162 | ; |
163 | } |
164 | } |
165 | |
166 | // CHECK: [B4 (ENTRY)] |
167 | // CHECK-NEXT: Succs (1): B2 |
168 | |
169 | // CHECK: [B1] |
170 | // CHECK-NEXT: 1: DoStmt (LoopExit) |
171 | // CHECK-NEXT: Preds (1): B2 |
172 | // CHECK-NEXT: Succs (1): B0 |
173 | |
174 | // CHECK: [B2] |
175 | // CHECK-NEXT: 1: false |
176 | // CHECK-NEXT: T: do ... while [B2.1] |
177 | // CHECK-NEXT: Preds (2): B3 B4 |
178 | // CHECK-NEXT: Succs (2): NULL B1 |
179 | |
180 | // CHECK: [B3] |
181 | // CHECK-NEXT: Succs (1): B2 |
182 | |
183 | // CHECK: [B0 (EXIT)] |
184 | // CHECK-NEXT: Preds (1): B1 |
185 | void check_dowhile1() { |
186 | do { |
187 | } while (false); |
188 | } |
189 | |
190 | // CHECK: [B6 (ENTRY)] |
191 | // CHECK-NEXT: Succs (1): B5 |
192 | |
193 | // CHECK: [B1] |
194 | // CHECK-NEXT: 1: DoStmt (LoopExit) |
195 | // CHECK-NEXT: 2: j |
196 | // CHECK-NEXT: 3: [B1.2]-- |
197 | // CHECK-NEXT: 4: return; |
198 | // CHECK-NEXT: Preds (1): B2 |
199 | // CHECK-NEXT: Succs (1): B0 |
200 | |
201 | // CHECK: [B2] |
202 | // CHECK-NEXT: 1: j |
203 | // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, int) |
204 | // CHECK-NEXT: 3: 20 |
205 | // CHECK-NEXT: 4: [B2.2] < [B2.3] |
206 | // CHECK-NEXT: T: do ... while [B2.4] |
207 | // CHECK-NEXT: Preds (1): B3 |
208 | // CHECK-NEXT: Succs (2): B4 B1 |
209 | |
210 | // CHECK: [B3] |
211 | // CHECK-NEXT: 1: j |
212 | // CHECK-NEXT: 2: 2 |
213 | // CHECK-NEXT: 3: [B3.1] += [B3.2] |
214 | // CHECK-NEXT: Preds (2): B4 B5 |
215 | // CHECK-NEXT: Succs (1): B2 |
216 | |
217 | // CHECK: [B4] |
218 | // CHECK-NEXT: Preds (1): B2 |
219 | // CHECK-NEXT: Succs (1): B3 |
220 | |
221 | // CHECK: [B5] |
222 | // CHECK-NEXT: 1: 2 |
223 | // CHECK-NEXT: 2: int j = 2; |
224 | // CHECK-NEXT: Preds (1): B6 |
225 | // CHECK-NEXT: Succs (1): B3 |
226 | |
227 | // CHECK: [B0 (EXIT)] |
228 | // CHECK-NEXT: Preds (1): B1 |
229 | void check_dowhile2() { |
230 | int j = 2; |
231 | do { |
232 | j += 2; |
233 | } while (j < 20); |
234 | j--; |
235 | return; |
236 | } |
237 | |
238 | // CHECK: [B10 (ENTRY)] |
239 | // CHECK-NEXT: Succs (1): B9 |
240 | |
241 | // CHECK: [B1] |
242 | // CHECK-NEXT: 1: WhileStmt (LoopExit) |
243 | // CHECK-NEXT: Preds (1): B8 |
244 | // CHECK-NEXT: Succs (1): B0 |
245 | |
246 | // CHECK: [B2] |
247 | // CHECK-NEXT: Preds (1): B3 |
248 | // CHECK-NEXT: Succs (1): B8 |
249 | |
250 | // CHECK: [B3] |
251 | // CHECK-NEXT: 1: ForStmt (LoopExit) |
252 | // CHECK-NEXT: Preds (1): B6 |
253 | // CHECK-NEXT: Succs (1): B2 |
254 | |
255 | // CHECK: [B4] |
256 | // CHECK-NEXT: 1: j |
257 | // CHECK-NEXT: 2: [B4.1]++ |
258 | // CHECK-NEXT: Preds (1): B5 |
259 | // CHECK-NEXT: Succs (1): B6 |
260 | |
261 | // CHECK: [B5] |
262 | // CHECK-NEXT: 1: i |
263 | // CHECK-NEXT: 2: [B5.1]++ |
264 | // CHECK-NEXT: Preds (1): B6 |
265 | // CHECK-NEXT: Succs (1): B4 |
266 | |
267 | // CHECK: [B6] |
268 | // CHECK-NEXT: 1: j |
269 | // CHECK-NEXT: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, int) |
270 | // CHECK-NEXT: 3: 6 |
271 | // CHECK-NEXT: 4: [B6.2] < [B6.3] |
272 | // CHECK-NEXT: T: for (...; [B6.4]; ...) |
273 | // CHECK-NEXT: Preds (2): B4 B7 |
274 | // CHECK-NEXT: Succs (2): B5 B3 |
275 | |
276 | // CHECK: [B7] |
277 | // CHECK-NEXT: 1: 1 |
278 | // CHECK-NEXT: 2: int j = 1; |
279 | // CHECK-NEXT: Preds (1): B8 |
280 | // CHECK-NEXT: Succs (1): B6 |
281 | |
282 | // CHECK: [B8] |
283 | // CHECK-NEXT: 1: i |
284 | // CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, int) |
285 | // CHECK-NEXT: 3: 2 |
286 | // CHECK-NEXT: 4: [B8.2] < [B8.3] |
287 | // CHECK-NEXT: T: while [B8.4] |
288 | // CHECK-NEXT: Preds (2): B2 B9 |
289 | // CHECK-NEXT: Succs (2): B7 B1 |
290 | |
291 | // CHECK: [B9] |
292 | // CHECK-NEXT: 1: 40 |
293 | // CHECK-NEXT: 2: -[B9.1] |
294 | // CHECK-NEXT: 3: int i = -40; |
295 | // CHECK-NEXT: Preds (1): B10 |
296 | // CHECK-NEXT: Succs (1): B8 |
297 | |
298 | // CHECK: [B0 (EXIT)] |
299 | // CHECK-NEXT: Preds (1): B1 |
300 | void nested_loops1() { |
301 | int i = -40; |
302 | while (i < 2) { |
303 | for (int j = 1; j < 6; j++) |
304 | i++; |
305 | } |
306 | } |
307 | |
308 | // CHECK: [B9 (ENTRY)] |
309 | // CHECK-NEXT: Succs (1): B8 |
310 | |
311 | // CHECK: [B1] |
312 | // CHECK-NEXT: 1: ForStmt (LoopExit) |
313 | // CHECK-NEXT: Preds (1): B7 |
314 | // CHECK-NEXT: Succs (1): B0 |
315 | |
316 | // CHECK: [B2] |
317 | // CHECK-NEXT: 1: j |
318 | // CHECK-NEXT: 2: [B2.1]++ |
319 | // CHECK-NEXT: Preds (1): B3 |
320 | // CHECK-NEXT: Succs (1): B7 |
321 | |
322 | // CHECK: [B3] |
323 | // CHECK-NEXT: 1: DoStmt (LoopExit) |
324 | // CHECK-NEXT: 2: i |
325 | // CHECK-NEXT: 3: [B3.2]-- |
326 | // CHECK-NEXT: Preds (1): B4 |
327 | // CHECK-NEXT: Succs (1): B2 |
328 | |
329 | // CHECK: [B4] |
330 | // CHECK-NEXT: 1: i |
331 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int) |
332 | // CHECK-NEXT: 3: 2 |
333 | // CHECK-NEXT: 4: [B4.2] < [B4.3] |
334 | // CHECK-NEXT: T: do ... while [B4.4] |
335 | // CHECK-NEXT: Preds (1): B5 |
336 | // CHECK-NEXT: Succs (2): B6 B3 |
337 | |
338 | // CHECK: [B5] |
339 | // CHECK-NEXT: 1: i |
340 | // CHECK-NEXT: 2: [B5.1]++ |
341 | // CHECK-NEXT: Preds (2): B6 B7 |
342 | // CHECK-NEXT: Succs (1): B4 |
343 | |
344 | // CHECK: [B6] |
345 | // CHECK-NEXT: Preds (1): B4 |
346 | // CHECK-NEXT: Succs (1): B5 |
347 | |
348 | // CHECK: [B7] |
349 | // CHECK-NEXT: 1: j |
350 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, int) |
351 | // CHECK-NEXT: 3: 6 |
352 | // CHECK-NEXT: 4: [B7.2] < [B7.3] |
353 | // CHECK-NEXT: T: for (...; [B7.4]; ...) |
354 | // CHECK-NEXT: Preds (2): B2 B8 |
355 | // CHECK-NEXT: Succs (2): B5 B1 |
356 | |
357 | // CHECK: [B8] |
358 | // CHECK-NEXT: 1: 40 |
359 | // CHECK-NEXT: 2: -[B8.1] |
360 | // CHECK-NEXT: 3: int i = -40; |
361 | // CHECK-NEXT: 4: 1 |
362 | // CHECK-NEXT: 5: int j = 1; |
363 | // CHECK-NEXT: Preds (1): B9 |
364 | // CHECK-NEXT: Succs (1): B7 |
365 | |
366 | // CHECK: [B0 (EXIT)] |
367 | // CHECK-NEXT: Preds (1): B1 |
368 | void nested_loops2() { |
369 | int i = -40; |
370 | for (int j = 1; j < 6; j++) { |
371 | do { |
372 | i++; |
373 | } while (i < 2); |
374 | i--; |
375 | } |
376 | } |
377 | |
378 | // CHECK: [B12 (ENTRY)] |
379 | // CHECK-NEXT: Succs (1): B11 |
380 | |
381 | // CHECK: [B1] |
382 | // CHECK-NEXT: 1: WhileStmt (LoopExit) |
383 | // CHECK-NEXT: 2: return; |
384 | // CHECK-NEXT: Preds (2): B3 B5 |
385 | // CHECK-NEXT: Succs (1): B0 |
386 | |
387 | // CHECK: [B2] |
388 | // CHECK-NEXT: Preds (1): B4 |
389 | // CHECK-NEXT: Succs (1): B5 |
390 | |
391 | // CHECK: [B3] |
392 | // CHECK-NEXT: T: break; |
393 | // CHECK-NEXT: Preds (1): B4 |
394 | // CHECK-NEXT: Succs (1): B1 |
395 | |
396 | // CHECK: [B4] |
397 | // CHECK-NEXT: 1: i |
398 | // CHECK-NEXT: 2: [B4.1]++ |
399 | // CHECK-NEXT: 3: i |
400 | // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, int) |
401 | // CHECK-NEXT: 5: 2 |
402 | // CHECK-NEXT: 6: [B4.4] % [B4.5] |
403 | // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
404 | // CHECK-NEXT: T: if [B4.7] |
405 | // CHECK-NEXT: Preds (1): B5 |
406 | // CHECK-NEXT: Succs (2): B3 B2 |
407 | |
408 | // CHECK: [B5] |
409 | // CHECK-NEXT: 1: i |
410 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, int) |
411 | // CHECK-NEXT: 3: 5 |
412 | // CHECK-NEXT: 4: [B5.2] < [B5.3] |
413 | // CHECK-NEXT: T: while [B5.4] |
414 | // CHECK-NEXT: Preds (2): B2 B6 |
415 | // CHECK-NEXT: Succs (2): B4 B1 |
416 | |
417 | // CHECK: [B6] |
418 | // CHECK-NEXT: 1: ForStmt (LoopExit) |
419 | // CHECK-NEXT: 2: 1 |
420 | // CHECK-NEXT: 3: int i = 1; |
421 | // CHECK-NEXT: Preds (2): B8 B10 |
422 | // CHECK-NEXT: Succs (1): B5 |
423 | |
424 | // CHECK: [B7] |
425 | // CHECK-NEXT: 1: i |
426 | // CHECK-NEXT: 2: [B7.1]++ |
427 | // CHECK-NEXT: Preds (1): B9 |
428 | // CHECK-NEXT: Succs (1): B10 |
429 | |
430 | // CHECK: [B8] |
431 | // CHECK-NEXT: T: break; |
432 | // CHECK-NEXT: Preds (1): B9 |
433 | // CHECK-NEXT: Succs (1): B6 |
434 | |
435 | // CHECK: [B9] |
436 | // CHECK-NEXT: 1: i |
437 | // CHECK-NEXT: 2: [B9.1] (ImplicitCastExpr, LValueToRValue, int) |
438 | // CHECK-NEXT: 3: 4 |
439 | // CHECK-NEXT: 4: [B9.2] == [B9.3] |
440 | // CHECK-NEXT: T: if [B9.4] |
441 | // CHECK-NEXT: Preds (1): B10 |
442 | // CHECK-NEXT: Succs (2): B8 B7 |
443 | |
444 | // CHECK: [B10] |
445 | // CHECK-NEXT: 1: i |
446 | // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, LValueToRValue, int) |
447 | // CHECK-NEXT: 3: 6 |
448 | // CHECK-NEXT: 4: [B10.2] < [B10.3] |
449 | // CHECK-NEXT: T: for (...; [B10.4]; ...) |
450 | // CHECK-NEXT: Preds (2): B7 B11 |
451 | // CHECK-NEXT: Succs (2): B9 B6 |
452 | |
453 | // CHECK: [B11] |
454 | // CHECK-NEXT: 1: 2 |
455 | // CHECK-NEXT: 2: int i = 2; |
456 | // CHECK-NEXT: Preds (1): B12 |
457 | // CHECK-NEXT: Succs (1): B10 |
458 | |
459 | // CHECK: [B0 (EXIT)] |
460 | // CHECK-NEXT: Preds (1): B1 |
461 | void check_break() |
462 | { |
463 | for(int i = 2; i < 6; i++) { |
464 | if(i == 4) |
465 | break; |
466 | } |
467 | |
468 | int i = 1; |
469 | while(i<5){ |
470 | i++; |
471 | if(i%2) |
472 | break; |
473 | } |
474 | |
475 | return; |
476 | } |
477 | |