1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true,cfg-loopexit=true -verify -std=c++11 %s
2 
3 void clang_analyzer_numTimesReached();
4 
5 int getNum();
6 void foo(int &);
7 // Testing for loops.
8 int simple_unroll1() {
9   int a[9];
10   int k = 42;
11   for (int i = 0; i < 9; i++) {
12     clang_analyzer_numTimesReached(); // expected-warning {{9}}
13     a[i] = 42;
14   }
15   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
16   return 0;
17 }
18 
19 int simple_unroll2() {
20   int a[9];
21   int k = 42;
22   int i;
23   for (i = 0; i < 9; i++) {
24     clang_analyzer_numTimesReached(); // expected-warning {{9}}
25     a[i] = 42;
26   }
27 
28   for (int j = 0; j <= 9; ++j) {
29     clang_analyzer_numTimesReached(); // expected-warning {{10}}
30     a[j] = 42;
31   }
32 
33   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
34   return 0;
35 }
36 
37 int simple_no_unroll1() {
38   int a[9];
39   int k = 42;
40   for (int i = 0; i < 9; i++) {
41     clang_analyzer_numTimesReached(); // expected-warning {{4}}
42     a[i] = 42;
43     foo(i);
44   }
45   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
46   return 0;
47 }
48 
49 int simple_no_unroll2() {
50   int a[9];
51   int k = 42;
52   int i;
53   for (i = 0; i < 9; i++) {
54     clang_analyzer_numTimesReached(); // expected-warning {{4}}
55     a[i] = 42;
56     i += getNum();
57   }
58   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
59   return 0;
60 }
61 
62 int simple_no_unroll3() {
63   int a[9];
64   int k = 42;
65   int i;
66   for (i = 0; i < 9; i++) {
67     clang_analyzer_numTimesReached(); // expected-warning {{4}}
68     a[i] = 42;
69     (void)&i;
70   }
71   int b = 22 / (k - 42); // no-warning
72   return 0;
73 }
74 
75 int simple_no_unroll4() {
76   int a[9];
77   int k = 42;
78   int i;
79   for (i = 0; i < 9; i++) {
80     clang_analyzer_numTimesReached(); // expected-warning {{4}}
81     a[i] = 42;
82     int &j = i;
83   }
84   int b = 22 / (k - 42); // no-warning
85   return 0;
86 }
87 
88 int simple_no_unroll5() {
89   int a[9];
90   int k = 42;
91   int i;
92   for (i = 0; i < 9; i++) {
93     clang_analyzer_numTimesReached(); // expected-warning {{4}}
94     a[i] = 42;
95     int &j{i};
96   }
97   int b = 22 / (k - 42); // no-warning
98   return 0;
99 }
100 
101 int escape_before_loop_no_unroll1() {
102   int a[9];
103   int k = 42;
104   int i;
105   int &j = i;
106   for (i = 0; i < 9; i++) {
107     clang_analyzer_numTimesReached(); // expected-warning {{4}}
108     a[i] = 42;
109   }
110   int b = 22 / (k - 42); // no-warning
111   return 0;
112 }
113 
114 int escape_before_loop_no_unroll2() {
115   int a[9];
116   int k = 42;
117   int i;
118   int *p = &i;
119   for (i = 0; i < 9; i++) {
120     clang_analyzer_numTimesReached(); // expected-warning {{4}}
121     a[i] = 42;
122   }
123   int b = 22 / (k - 42); // no-warning
124   return 0;
125 }
126 
127 int escape_before_loop_no_unroll3() {
128   int a[9];
129   int k = 42;
130   int i;
131   foo(i);
132   for (i = 0; i < 9; i++) {
133     clang_analyzer_numTimesReached(); // expected-warning {{4}}
134     a[i] = 42;
135   }
136   int b = 22 / (k - 42); // no-warning
137   return 0;
138 }
139 
140 int nested_outer_unrolled() {
141   int a[9];
142   int k = 42;
143   int j = 0;
144   for (int i = 0; i < 9; i++) {
145     clang_analyzer_numTimesReached(); // expected-warning {{16}}
146     for (j = 0; j < getNum(); ++j) {
147       clang_analyzer_numTimesReached(); // expected-warning {{15}}
148       a[j] = 22;
149     }
150     a[i] = 42;
151   }
152   int b = 22 / (k - 42); // no-warning
153   return 0;
154 }
155 
156 int nested_inner_unrolled() {
157   int a[9];
158   int k = 42;
159   int j = 0;
160   for (int i = 0; i < getNum(); i++) {
161     clang_analyzer_numTimesReached(); // expected-warning {{4}}
162     for (j = 0; j < 8; ++j) {
163       clang_analyzer_numTimesReached(); // expected-warning {{32}}
164       a[j] = 22;
165     }
166     a[i] = 42;
167   }
168   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
169   return 0;
170 }
171 
172 int nested_both_unrolled() {
173   int a[9];
174   int k = 42;
175   int j = 0;
176   for (int i = 0; i < 7; i++) {
177     clang_analyzer_numTimesReached(); // expected-warning {{7}}
178     for (j = 0; j < 6; ++j) {
179       clang_analyzer_numTimesReached(); // expected-warning {{42}}
180       a[j] = 22;
181     }
182     a[i] = 42;
183   }
184   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
185   return 0;
186 }
187 
188 int simple_known_bound_loop() {
189   for (int i = 2; i < 12; i++) {
190     // This function is inlined in nested_inlined_unroll1()
191     clang_analyzer_numTimesReached(); // expected-warning {{90}}
192   }
193   return 0;
194 }
195 
196 int simple_unknown_bound_loop() {
197   for (int i = 2; i < getNum(); i++) {
198     clang_analyzer_numTimesReached(); // expected-warning {{10}}
199   }
200   return 0;
201 }
202 
203 int nested_inlined_unroll1() {
204   int k;
205   for (int i = 0; i < 9; i++) {
206     clang_analyzer_numTimesReached(); // expected-warning {{9}}
207     k = simple_known_bound_loop();    // no reevaluation without inlining
208   }
209   int a = 22 / k; // expected-warning {{Division by zero}}
210   return 0;
211 }
212 
213 int nested_inlined_no_unroll1() {
214   int k;
215   for (int i = 0; i < 9; i++) {
216     clang_analyzer_numTimesReached(); // expected-warning {{26}}
217     k = simple_unknown_bound_loop();  // reevaluation without inlining
218   }
219   int a = 22 / k; // no-warning
220   return 0;
221 }
222 
223 
224 int recursion_unroll1(bool b) {
225   int k = 2;
226   for (int i = 0; i < 5; i++) {
227     clang_analyzer_numTimesReached(); // expected-warning {{14}}
228     if(i == 0 && b)
229       recursion_unroll1(false);
230     clang_analyzer_numTimesReached(); // expected-warning {{15}}
231   }
232   int a = 22 / k; // no-warning
233   return 0;
234 }
235 
236 int recursion_unroll2(bool b) {
237   int k = 0;
238   for (int i = 0; i < 5; i++) {
239     clang_analyzer_numTimesReached(); // expected-warning {{10}}
240     if(i == 0 && b)
241       recursion_unroll2(false);
242     clang_analyzer_numTimesReached(); // expected-warning {{10}}
243   }
244   int a = 22 / k; // expected-warning {{Division by zero}}
245   return 0;
246 }
247 
248 int recursion_unroll3(bool b) {
249   int k = 2;
250   for (int i = 0; i < 5; i++) {
251     clang_analyzer_numTimesReached(); // expected-warning {{10}}
252     if(i == 4 && b) {
253       recursion_unroll3(false);
254       break;
255     }
256     clang_analyzer_numTimesReached(); // expected-warning {{10}}
257   }
258   int a = 22 / k;
259   return 0;
260 }
261 
262 int recursion_unroll4(bool b) {
263   int k = 2;
264   for (int i = 0; i < 5; i++) {
265     clang_analyzer_numTimesReached(); // expected-warning {{14}}
266     if(i == 0 && b) {
267       recursion_unroll4(false);
268       continue;
269     }
270     clang_analyzer_numTimesReached(); // expected-warning {{14}}
271   }
272   int a = 22 / k;
273   return 0;
274 }
275