1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true -analyzer-stats -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   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
28   return 0;
29 }
30 
31 int simple_no_unroll1() {
32   int a[9];
33   int k = 42;
34   for (int i = 0; i < 9; i++) {
35     clang_analyzer_numTimesReached(); // expected-warning {{4}}
36     a[i] = 42;
37     foo(i);
38   }
39   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
40   return 0;
41 }
42 
43 int simple_no_unroll2() {
44   int a[9];
45   int k = 42;
46   int i;
47   for (i = 0; i < 9; i++) {
48     clang_analyzer_numTimesReached(); // expected-warning {{4}}
49     a[i] = 42;
50     i += getNum();
51   }
52   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
53   return 0;
54 }
55 
56 int simple_no_unroll3() {
57   int a[9];
58   int k = 42;
59   int i;
60   for (i = 0; i < 9; i++) {
61     clang_analyzer_numTimesReached(); // expected-warning {{4}}
62     a[i] = 42;
63     (void)&i;
64   }
65   int b = 22 / (k - 42); // no-warning
66   return 0;
67 }
68 
69 int simple_no_unroll4() {
70   int a[9];
71   int k = 42;
72   int i;
73   for (i = 0; i < 9; i++) {
74     clang_analyzer_numTimesReached(); // expected-warning {{4}}
75     a[i] = 42;
76     int &j = i;
77   }
78   int b = 22 / (k - 42); // no-warning
79   return 0;
80 }
81 
82 int simple_no_unroll5() {
83   int a[9];
84   int k = 42;
85   int i;
86   for (i = 0; i < 9; i++) {
87     clang_analyzer_numTimesReached(); // expected-warning {{4}}
88     a[i] = 42;
89     int &j{i};
90   }
91   int b = 22 / (k - 42); // no-warning
92   return 0;
93 }
94 
95 int nested_outer_unrolled() {
96   int a[9];
97   int k = 42;
98   int j = 0;
99   for (int i = 0; i < 9; i++) {
100     clang_analyzer_numTimesReached(); // expected-warning {{16}}
101     for (j = 0; j < getNum(); ++j) {
102       clang_analyzer_numTimesReached(); // expected-warning {{15}}
103       a[j] = 22;
104     }
105     a[i] = 42;
106   }
107   int b = 22 / (k - 42); // no-warning
108   return 0;
109 }
110 
111 int nested_inner_unrolled() {
112   int a[9];
113   int k = 42;
114   int j = 0;
115   for (int i = 0; i < getNum(); i++) {
116     clang_analyzer_numTimesReached(); // expected-warning {{4}}
117     for (j = 0; j < 8; ++j) {
118       clang_analyzer_numTimesReached(); // expected-warning {{32}}
119       a[j] = 22;
120     }
121     a[i] = 42;
122   }
123   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
124   return 0;
125 }
126 
127 int nested_both_unrolled() {
128   int a[9];
129   int k = 42;
130   int j = 0;
131   for (int i = 0; i < 7; i++) {
132     clang_analyzer_numTimesReached(); // expected-warning {{7}}
133     for (j = 0; j < 6; ++j) {
134       clang_analyzer_numTimesReached(); // expected-warning {{42}}
135       a[j] = 22;
136     }
137     a[i] = 42;
138   }
139   int b = 22 / (k - 42); // expected-warning {{Division by zero}}
140   return 0;
141 }
142 
143 int simple_known_bound_loop() {
144   for (int i = 2; i < 12; i++) {
145     // This function is inlined in nested_inlined_unroll1()
146     clang_analyzer_numTimesReached(); // expected-warning {{90}}
147   }
148   return 0;
149 }
150 
151 int simple_unknown_bound_loop() {
152   for (int i = 2; i < getNum(); i++) {
153     clang_analyzer_numTimesReached(); // expected-warning {{10}}
154   }
155   return 0;
156 }
157 
158 int nested_inlined_unroll1() {
159   int k;
160   for (int i = 0; i < 9; i++) {
161     clang_analyzer_numTimesReached(); // expected-warning {{9}}
162     k = simple_known_bound_loop();    // no reevaluation without inlining
163   }
164   int a = 22 / k; // expected-warning {{Division by zero}}
165   return 0;
166 }
167 
168 int nested_inlined_no_unroll1() {
169   int k;
170   for (int i = 0; i < 9; i++) {
171     clang_analyzer_numTimesReached(); // expected-warning {{26}}
172     k = simple_unknown_bound_loop();  // reevaluation without inlining
173   }
174   int a = 22 / k; // no-warning
175   return 0;
176 }
177