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
check_forloop1()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
check_forloop2()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
check_while1()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
check_while2()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
check_while3()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
check_dowhile1()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
check_dowhile2()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
nested_loops1()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
nested_loops2()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
check_break()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