Clang Project

clang_source_code/test/Analysis/loop-unrolling.cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true,cfg-loopexit=true -verify -std=c++11 -analyzer-config exploration_strategy=unexplored_first_queue %s
2// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true,cfg-loopexit=true,exploration_strategy=dfs -verify -std=c++11 -DDFS=1 %s
3
4void clang_analyzer_numTimesReached();
5void clang_analyzer_warnIfReached();
6
7int getNum();
8void foo(int &);
9
10int simple_unroll1() {
11  int a[9];
12  int k = 42;
13  for (int i = 0; i < 9; i++) {
14    clang_analyzer_numTimesReached(); // expected-warning {{9}}
15    a[i] = 42;
16  }
17  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
18  return 0;
19}
20
21int simple_unroll2() {
22  int a[9];
23  int k = 42;
24  int i;
25  for (i = 0; i < 9; i++) {
26    clang_analyzer_numTimesReached(); // expected-warning {{9}}
27    a[i] = 42;
28  }
29
30  for (int j = 0; j <= 9; ++j) {
31    clang_analyzer_numTimesReached(); // expected-warning {{10}}
32    a[j] = 42;
33  }
34
35  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
36  return 0;
37}
38
39int simple_unroll3_unsigned() {
40  int a[9];
41  int k = 42;
42  for (unsigned i = 0; i < 9; i++) {
43    clang_analyzer_numTimesReached(); // expected-warning {{9}}
44    a[i] = 42;
45  }
46  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
47  return 0;
48}
49
50int simple_unroll4_unsigned() {
51  int a[9];
52  int k = 42;
53  unsigned i;
54  for (i = (0); i < 9; i++) {
55    clang_analyzer_numTimesReached(); // expected-warning {{9}}
56    a[i] = 42;
57  }
58  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
59  return 0;
60}
61
62int simple_no_unroll1() {
63  int a[9];
64  int k = 42;
65  for (int i = 0; i < 9; i++) {
66    clang_analyzer_numTimesReached(); // expected-warning {{4}}
67    a[i] = 42;
68    foo(i);
69  }
70  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
71  return 0;
72}
73
74int simple_no_unroll2() {
75  int a[9];
76  int k = 42;
77  int i;
78  for (i = 0; i < 9; i++) {
79    clang_analyzer_numTimesReached(); // expected-warning {{4}}
80    a[i] = 42;
81    i += getNum();
82  }
83  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
84  return 0;
85}
86
87int simple_no_unroll3() {
88  int a[9];
89  int k = 42;
90  for (int i = 0; i < 9; i++) {
91    clang_analyzer_numTimesReached(); // expected-warning {{4}}
92    a[i] = 42;
93    (void)&i;
94  }
95  int b = 22 / (k - 42); // no-warning
96  return 0;
97}
98
99int simple_no_unroll4() {
100  int a[9];
101  int k = 42;
102  int i;
103  for (i = 0; i < 9; i++) {
104    clang_analyzer_numTimesReached(); // expected-warning {{4}}
105    a[i] = 42;
106    int &j = i;
107  }
108  int b = 22 / (k - 42); // no-warning
109  return 0;
110}
111
112int simple_no_unroll5() {
113  int a[9];
114  int k = 42;
115  int i;
116  for (i = 0; i < 9; i++) {
117    clang_analyzer_numTimesReached(); // expected-warning {{4}}
118    a[i] = 42;
119    int &j{i};
120  }
121  int b = 22 / (k - 42); // no-warning
122  return 0;
123}
124
125int no_unroll_assignment() {
126  for (int i = 0; i < 9; i++) {
127    i = i + 1;
128    clang_analyzer_numTimesReached(); // expected-warning {{4}}
129  }
130  return 0;
131}
132
133int no_unroll_assignment2() {
134  for (int i = 0; i < 9; i++) {
135    i *= 2;
136    clang_analyzer_numTimesReached(); // expected-warning {{4}}
137  }
138  return 0;
139}
140
141int no_unroll_assignment3() {
142  for (int i = 128; i > 0; i--) {
143    i /= 2;
144    clang_analyzer_numTimesReached(); // expected-warning {{4}}
145  }
146  return 0;
147}
148
149int no_unroll_assignment4() {
150  for (int i = 0; i < 9; i++) {
151    i -= 2;
152    clang_analyzer_numTimesReached(); // expected-warning {{4}}
153  }
154  return 0;
155}
156
157int no_unroll_assignment5() {
158  for (int i = 0; i < 9; i++) {
159    i += 1;
160    clang_analyzer_numTimesReached(); // expected-warning {{4}}
161  }
162  return 0;
163}
164
165int no_unroll_assignment6() {
166  for (int i = 128; i > 0; i--) {
167    i >>= 1;
168    clang_analyzer_numTimesReached(); // expected-warning {{4}}
169  }
170  return 0;
171}
172
173int no_unroll_assignment7() {
174  for (int i = 0; i < 512; i++) {
175    i <<= 1;
176    clang_analyzer_numTimesReached(); // expected-warning {{4}}
177  }
178  return 0;
179}
180
181int no_unroll_assignment8() {
182  for (int i = 0; i < 9; i++) {
183    i %= 8;
184    clang_analyzer_numTimesReached(); // expected-warning {{4}}
185  }
186  return 0;
187}
188
189int no_unroll_assignment9() {
190  for (int i = 0; i < 9; i++) {
191    i &= 31;
192    clang_analyzer_numTimesReached(); // expected-warning {{4}}
193  }
194  return 0;
195}
196
197int no_unroll_assignment10() {
198  for (int i = 0; i < 9; i++) {
199    i |= 2;
200    clang_analyzer_numTimesReached(); // expected-warning {{4}}
201  }
202  return 0;
203}
204
205int no_unroll_assignment11() {
206  for (int i = 0; i < 9; i++) {
207    i ^= 2;
208    clang_analyzer_numTimesReached(); // expected-warning {{4}}
209  }
210  return 0;
211}
212
213int make_new_branches_loop_cached() {
214  for (int i = 0; i < 8; i++) {
215    clang_analyzer_numTimesReached(); // expected-warning {{4}}
216    if (getNum()) {
217      (void)i; // Since this Stmt does not change the State the analyzer
218               // won't make a new execution path but reuse the earlier nodes.
219    }
220  }
221  clang_analyzer_warnIfReached(); // no-warning
222  return 0;
223}
224
225int make_new_branches_loop_uncached() {
226  int l = 2;
227  for (int i = 0; i < 8; i++) {
228    clang_analyzer_numTimesReached(); // expected-warning {{10}}
229    if (getNum()) {
230      ++l;
231    }
232  }
233  clang_analyzer_warnIfReached(); // no-warning
234  return 0;
235}
236
237int make_new_branches_loop_uncached2() {
238  int l = 2;
239  for (int i = 0; i < 8; i++) {
240    clang_analyzer_numTimesReached(); // expected-warning {{10}}
241    if (getNum()) {
242      ++l;
243    }
244    (void)&i; // This ensures that the loop won't be unrolled.
245  }
246  clang_analyzer_warnIfReached(); // no-warning
247  return 0;
248}
249
250
251int escape_before_loop_no_unroll1() {
252  int a[9];
253  int k = 42;
254  int i;
255  int &j = i;
256  for (i = 0; i < 9; i++) {
257    clang_analyzer_numTimesReached(); // expected-warning {{4}}
258    a[i] = 42;
259  }
260  int b = 22 / (k - 42); // no-warning
261  return 0;
262}
263
264int escape_before_loop_no_unroll2() {
265  int a[9];
266  int k = 42;
267  int i;
268  int *p = &i;
269  for (i = 0; i < 9; i++) {
270    clang_analyzer_numTimesReached(); // expected-warning {{4}}
271    a[i] = 42;
272  }
273  int b = 22 / (k - 42); // no-warning
274  return 0;
275}
276
277int escape_before_loop_no_unroll3() {
278  int a[9];
279  int k = 42;
280  int i;
281  foo(i);
282  for (i = 0; i < 9; i++) {
283    clang_analyzer_numTimesReached(); // expected-warning {{4}}
284    a[i] = 42;
285  }
286  int b = 22 / (k - 42); // no-warning
287  return 0;
288}
289
290int nested_outer_unrolled() {
291  int a[9];
292  int k = 42;
293  int j = 0;
294  for (int i = 0; i < 9; i++) {
295    clang_analyzer_numTimesReached(); // expected-warning {{1}}
296    for (j = 0; j < 9; ++j) {
297      clang_analyzer_numTimesReached(); // expected-warning {{4}}
298      a[j] = 22;
299      (void)&j; // ensures that the inner loop won't be unrolled
300    }
301    a[i] = 42;
302  }
303  int b = 22 / (k - 42); // no-warning
304  return 0;
305}
306
307int nested_inner_unrolled() {
308  int a[9];
309  int k = 42;
310  int j = 0;
311  for (int i = 0; i < getNum(); i++) {
312    clang_analyzer_numTimesReached(); // expected-warning {{4}}
313    for (j = 0; j < 8; ++j) {
314      clang_analyzer_numTimesReached(); // expected-warning {{32}}
315      a[j] = 22;
316    }
317    a[i] = 42;
318  }
319  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
320  return 0;
321}
322
323int nested_both_unrolled() {
324  int a[9];
325  int k = 42;
326  int j = 0;
327  for (int i = 0; i < 7; i++) {
328    clang_analyzer_numTimesReached(); // expected-warning {{7}}
329    for (j = 0; j < 6; ++j) {
330      clang_analyzer_numTimesReached(); // expected-warning {{42}}
331      a[j] = 22;
332    }
333    a[i] = 42;
334  }
335  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
336  return 0;
337}
338
339int simple_known_bound_loop() {
340  for (int i = 2; i < 12; i++) {
341    // This function is inlined in nested_inlined_unroll1()
342    clang_analyzer_numTimesReached(); // expected-warning {{90}}
343  }
344  return 0;
345}
346
347int simple_unknown_bound_loop() {
348  for (int i = 2; i < getNum(); i++) {
349#ifdef DFS
350    clang_analyzer_numTimesReached(); // expected-warning {{10}}
351#else
352    clang_analyzer_numTimesReached(); // expected-warning {{13}}
353#endif
354  }
355  return 0;
356}
357
358int nested_inlined_unroll1() {
359  int k;
360  for (int i = 0; i < 9; i++) {
361    clang_analyzer_numTimesReached(); // expected-warning {{9}}
362    k = simple_known_bound_loop();    // no reevaluation without inlining
363  }
364  int a = 22 / k; // expected-warning {{Division by zero}}
365  return 0;
366}
367
368int nested_inlined_no_unroll1() {
369  int k;
370  for (int i = 0; i < 9; i++) {
371#ifdef ANALYZER_CM_Z3
372    clang_analyzer_numTimesReached(); // expected-warning {{13}}
373#else
374    clang_analyzer_numTimesReached(); // expected-warning {{15}}
375#endif
376    k = simple_unknown_bound_loop();  // reevaluation without inlining, splits the state as well
377  }
378  int a = 22 / k; // no-warning
379  return 0;
380}
381
382int recursion_unroll1(bool b) {
383  int k = 2;
384  for (int i = 0; i < 5; i++) {
385    clang_analyzer_numTimesReached(); // expected-warning {{13}}
386    if (i == 0 && b)                  // Splits the state in the first iteration but the recursion
387                                      // call will be unrolled anyway since the condition is known there.
388      recursion_unroll1(false);
389    clang_analyzer_numTimesReached(); // expected-warning {{14}}
390  }
391  int a = 22 / k; // no-warning
392  return 0;
393}
394
395int recursion_unroll2(bool b) {
396  int k = 0;
397  for (int i = 0; i < 5; i++) {
398    clang_analyzer_numTimesReached(); // expected-warning {{9}}
399    if (i == 0 && b)
400      recursion_unroll2(false);
401    clang_analyzer_numTimesReached(); // expected-warning {{9}}
402  }
403  int a = 22 / k; // expected-warning {{Division by zero}}
404  return 0;
405}
406
407int recursion_unroll3(bool b) {
408  int k = 2;
409  for (int i = 0; i < 5; i++) {
410    clang_analyzer_numTimesReached(); // expected-warning {{10}}
411    if (i == 4 && b) {
412      recursion_unroll3(false);
413      break;
414    }
415    clang_analyzer_numTimesReached(); // expected-warning {{10}}
416  }
417  int a = 22 / k;
418  return 0;
419}
420
421int recursion_unroll4(bool b) {
422  int k = 2;
423  for (int i = 0; i < 5; i++) {
424    clang_analyzer_numTimesReached(); // expected-warning {{13}}
425    if (i == 0 && b) {
426      recursion_unroll4(false);
427      continue;
428    }
429    clang_analyzer_numTimesReached(); // expected-warning {{13}}
430  }
431  int a = 22 / k;
432  return 0;
433}
434
435int loop_exit_while_empty_loop_stack() {
436  if (getNum())
437    for (int i = 1; i < 8; i++)
438      ;
439  return 0;
440}
441
442int num_steps_on_limit() {
443  for (int i = 0; i < 128; i++) {
444    clang_analyzer_numTimesReached(); // expected-warning {{128}}
445  }
446  clang_analyzer_numTimesReached(); // expected-warning {{1}}
447  return 0;
448}
449
450int num_steps_over_limit1() {
451  for (int i = 0; i < 129; i++) {
452    clang_analyzer_numTimesReached(); // expected-warning {{4}}
453  }
454  return 0;
455}
456
457int num_steps_on_limit2() {
458  for (int i = 0; i < 2; i++) {
459    for (int j = 0; j < 64; j++) {
460      clang_analyzer_numTimesReached(); // expected-warning {{128}}
461    }
462  }
463  return 0;
464}
465
466int num_steps_over_limit2() {
467  for (int i = 0; i < 2; i++) {
468    clang_analyzer_numTimesReached(); // expected-warning {{1}}
469    for (int j = 0; j <= 64; j++) {
470      clang_analyzer_numTimesReached(); // expected-warning {{4}}
471    }
472  }
473  return 0;
474}
475
476int num_steps_on_limit3() {
477  for (int i = 0; i < getNum(); i++) {
478    clang_analyzer_numTimesReached(); // expected-warning {{4}}
479    for (int j = 0; j < 32; j++) {
480      clang_analyzer_numTimesReached(); // expected-warning {{128}}
481    }
482  }
483  return 0;
484}
485
486int num_steps_over_limit3() {
487  for (int i = 0; i < getNum(); i++) {
488    clang_analyzer_numTimesReached(); // expected-warning {{1}}
489    for (int j = 0; j < 33; j++) {
490      clang_analyzer_numTimesReached(); // expected-warning {{4}}
491    }
492  }
493  return 0;
494}
495
496
497void pr34943() {
498  for (int i = 0; i < 6L; ++i) {
499    clang_analyzer_numTimesReached(); // expected-warning {{6}}
500  }
501}
502