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 void clang_analyzer_warnIfReached(); 5 6 int getNum(); 7 void foo(int &); 8 9 int simple_unroll1() { 10 int a[9]; 11 int k = 42; 12 for (int i = 0; i < 9; i++) { 13 clang_analyzer_numTimesReached(); // expected-warning {{9}} 14 a[i] = 42; 15 } 16 int b = 22 / (k - 42); // expected-warning {{Division by zero}} 17 return 0; 18 } 19 20 int simple_unroll2() { 21 int a[9]; 22 int k = 42; 23 int i; 24 for (i = 0; i < 9; i++) { 25 clang_analyzer_numTimesReached(); // expected-warning {{9}} 26 a[i] = 42; 27 } 28 29 for (int j = 0; j <= 9; ++j) { 30 clang_analyzer_numTimesReached(); // expected-warning {{10}} 31 a[j] = 42; 32 } 33 34 int b = 22 / (k - 42); // expected-warning {{Division by zero}} 35 return 0; 36 } 37 38 int simple_no_unroll1() { 39 int a[9]; 40 int k = 42; 41 for (int i = 0; i < 9; i++) { 42 clang_analyzer_numTimesReached(); // expected-warning {{4}} 43 a[i] = 42; 44 foo(i); 45 } 46 int b = 22 / (k - 42); // expected-warning {{Division by zero}} 47 return 0; 48 } 49 50 int simple_no_unroll2() { 51 int a[9]; 52 int k = 42; 53 int i; 54 for (i = 0; i < 9; i++) { 55 clang_analyzer_numTimesReached(); // expected-warning {{4}} 56 a[i] = 42; 57 i += getNum(); 58 } 59 int b = 22 / (k - 42); // expected-warning {{Division by zero}} 60 return 0; 61 } 62 63 int simple_no_unroll3() { 64 int a[9]; 65 int k = 42; 66 for (int 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 make_new_branches_loop_cached() { 102 for (int i = 0; i < 8; i++) { 103 clang_analyzer_numTimesReached(); // expected-warning {{4}} 104 if(getNum()){ 105 (void) i; // Since this Stmt does not change the State the analyzer 106 // won't make a new execution path but reuse the earlier nodes. 107 } 108 } 109 clang_analyzer_warnIfReached(); // no-warning 110 return 0; 111 } 112 113 int make_new_branches_loop_uncached() { 114 int l = 2; 115 for (int i = 0; i < 8; i++) { 116 clang_analyzer_numTimesReached(); // expected-warning {{10}} 117 if(getNum()){ 118 ++l; 119 } 120 } 121 clang_analyzer_warnIfReached(); // no-warning 122 return 0; 123 } 124 125 int make_new_branches_loop_uncached2() { 126 int l = 2; 127 for (int i = 0; i < 8; i++) { 128 clang_analyzer_numTimesReached(); // expected-warning {{10}} 129 if(getNum()){ 130 ++l; 131 } 132 (void)&i; // This ensures that the loop won't be unrolled. 133 } 134 clang_analyzer_warnIfReached(); // no-warning 135 return 0; 136 } 137 138 139 int escape_before_loop_no_unroll1() { 140 int a[9]; 141 int k = 42; 142 int i; 143 int &j = i; 144 for (i = 0; i < 9; i++) { 145 clang_analyzer_numTimesReached(); // expected-warning {{4}} 146 a[i] = 42; 147 } 148 int b = 22 / (k - 42); // no-warning 149 return 0; 150 } 151 152 int escape_before_loop_no_unroll2() { 153 int a[9]; 154 int k = 42; 155 int i; 156 int *p = &i; 157 for (i = 0; i < 9; i++) { 158 clang_analyzer_numTimesReached(); // expected-warning {{4}} 159 a[i] = 42; 160 } 161 int b = 22 / (k - 42); // no-warning 162 return 0; 163 } 164 165 int escape_before_loop_no_unroll3() { 166 int a[9]; 167 int k = 42; 168 int i; 169 foo(i); 170 for (i = 0; i < 9; i++) { 171 clang_analyzer_numTimesReached(); // expected-warning {{4}} 172 a[i] = 42; 173 } 174 int b = 22 / (k - 42); // no-warning 175 return 0; 176 } 177 178 int nested_outer_unrolled() { 179 int a[9]; 180 int k = 42; 181 int j = 0; 182 for (int i = 0; i < 9; i++) { 183 clang_analyzer_numTimesReached(); // expected-warning {{1}} 184 for (j = 0; j < 9; ++j) { 185 clang_analyzer_numTimesReached(); // expected-warning {{4}} 186 a[j] = 22; 187 (void) &j; // ensures that the inner loop won't be unrolled 188 } 189 a[i] = 42; 190 } 191 int b = 22 / (k - 42); // no-warning 192 return 0; 193 } 194 195 int nested_inner_unrolled() { 196 int a[9]; 197 int k = 42; 198 int j = 0; 199 for (int i = 0; i < getNum(); i++) { 200 clang_analyzer_numTimesReached(); // expected-warning {{4}} 201 for (j = 0; j < 8; ++j) { 202 clang_analyzer_numTimesReached(); // expected-warning {{32}} 203 a[j] = 22; 204 } 205 a[i] = 42; 206 } 207 int b = 22 / (k - 42); // expected-warning {{Division by zero}} 208 return 0; 209 } 210 211 int nested_both_unrolled() { 212 int a[9]; 213 int k = 42; 214 int j = 0; 215 for (int i = 0; i < 7; i++) { 216 clang_analyzer_numTimesReached(); // expected-warning {{7}} 217 for (j = 0; j < 6; ++j) { 218 clang_analyzer_numTimesReached(); // expected-warning {{42}} 219 a[j] = 22; 220 } 221 a[i] = 42; 222 } 223 int b = 22 / (k - 42); // expected-warning {{Division by zero}} 224 return 0; 225 } 226 227 int simple_known_bound_loop() { 228 for (int i = 2; i < 12; i++) { 229 // This function is inlined in nested_inlined_unroll1() 230 clang_analyzer_numTimesReached(); // expected-warning {{90}} 231 } 232 return 0; 233 } 234 235 int simple_unknown_bound_loop() { 236 for (int i = 2; i < getNum(); i++) { 237 clang_analyzer_numTimesReached(); // expected-warning {{10}} 238 } 239 return 0; 240 } 241 242 int nested_inlined_unroll1() { 243 int k; 244 for (int i = 0; i < 9; i++) { 245 clang_analyzer_numTimesReached(); // expected-warning {{9}} 246 k = simple_known_bound_loop(); // no reevaluation without inlining 247 } 248 int a = 22 / k; // expected-warning {{Division by zero}} 249 return 0; 250 } 251 252 int nested_inlined_no_unroll1() { 253 int k; 254 for (int i = 0; i < 9; i++) { 255 clang_analyzer_numTimesReached(); // expected-warning {{15}} 256 k = simple_unknown_bound_loop(); // reevaluation without inlining, splits the state as well 257 } 258 int a = 22 / k; // no-warning 259 return 0; 260 } 261 262 int recursion_unroll1(bool b) { 263 int k = 2; 264 for (int i = 0; i < 5; i++) { 265 clang_analyzer_numTimesReached(); // expected-warning {{13}} 266 if(i == 0 && b) // Splits the state in the first iteration but the recursion 267 // call will be unrolled anyway since the condition is known there. 268 recursion_unroll1(false); 269 clang_analyzer_numTimesReached(); // expected-warning {{14}} 270 } 271 int a = 22 / k; // no-warning 272 return 0; 273 } 274 275 int recursion_unroll2(bool b) { 276 int k = 0; 277 for (int i = 0; i < 5; i++) { 278 clang_analyzer_numTimesReached(); // expected-warning {{9}} 279 if(i == 0 && b) 280 recursion_unroll2(false); 281 clang_analyzer_numTimesReached(); // expected-warning {{9}} 282 } 283 int a = 22 / k; // expected-warning {{Division by zero}} 284 return 0; 285 } 286 287 int recursion_unroll3(bool b) { 288 int k = 2; 289 for (int i = 0; i < 5; i++) { 290 clang_analyzer_numTimesReached(); // expected-warning {{10}} 291 if (i == 4 && b) { 292 recursion_unroll3(false); 293 break; 294 } 295 clang_analyzer_numTimesReached(); // expected-warning {{10}} 296 } 297 int a = 22 / k; 298 return 0; 299 } 300 301 int recursion_unroll4(bool b) { 302 int k = 2; 303 for (int i = 0; i < 5; i++) { 304 clang_analyzer_numTimesReached(); // expected-warning {{13}} 305 if(i == 0 && b) { 306 recursion_unroll4(false); 307 continue; 308 } 309 clang_analyzer_numTimesReached(); // expected-warning {{13}} 310 } 311 int a = 22 / k; 312 return 0; 313 } 314 315 int loop_exit_while_empty_loop_stack() { 316 if (getNum()) 317 for (int i = 1; i < 8; i++) 318 ; 319 return 0; 320 } 321 322 int num_steps_on_limit() { 323 for (int i = 0; i < 128; i++) { 324 clang_analyzer_numTimesReached(); // expected-warning {{128}} 325 } 326 clang_analyzer_numTimesReached(); // expected-warning {{1}} 327 return 0; 328 } 329 330 int num_steps_over_limit1() { 331 for (int i = 0; i < 129; i++) { 332 clang_analyzer_numTimesReached(); // expected-warning {{4}} 333 } 334 return 0; 335 } 336 337 int num_steps_on_limit2() { 338 for (int i = 0; i < 2; i++) { 339 for (int j = 0; j < 64; j++) { 340 clang_analyzer_numTimesReached(); // expected-warning {{128}} 341 } 342 } 343 return 0; 344 } 345 346 int num_steps_over_limit2() { 347 for (int i = 0; i < 2; i++) { 348 clang_analyzer_numTimesReached(); // expected-warning {{1}} 349 for (int j = 0; j <= 64; j++) { 350 clang_analyzer_numTimesReached(); // expected-warning {{4}} 351 } 352 } 353 return 0; 354 } 355 356 int num_steps_on_limit3() { 357 for (int i = 0; i < getNum(); i++) { 358 clang_analyzer_numTimesReached(); // expected-warning {{4}} 359 for (int j = 0; j < 32; j++) { 360 clang_analyzer_numTimesReached(); // expected-warning {{128}} 361 } 362 } 363 return 0; 364 } 365 366 int num_steps_over_limit3() { 367 for (int i = 0; i < getNum(); i++) { 368 clang_analyzer_numTimesReached(); // expected-warning {{1}} 369 for (int j = 0; j < 33; j++) { 370 clang_analyzer_numTimesReached(); // expected-warning {{4}} 371 } 372 } 373 return 0; 374 } 375 376