1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true,cfg-loopexit=true -verify -std=c++14 -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++14 -DDFS=1 %s 3 4 void clang_analyzer_numTimesReached(); 5 void clang_analyzer_warnIfReached(); 6 7 int getNum(); 8 void foo(int &); 9 simple_unroll1()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 simple_unroll2()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 simple_unroll3_unsigned()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 simple_unroll4_unsigned()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 simple_no_unroll1()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 simple_no_unroll2()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 simple_no_unroll3()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 simple_no_unroll4()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 simple_no_unroll5()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 no_unroll_assignment()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 no_unroll_assignment2()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 no_unroll_assignment3()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 no_unroll_assignment4()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 no_unroll_assignment5()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 no_unroll_assignment6()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 no_unroll_assignment7()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 no_unroll_assignment8()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 no_unroll_assignment9()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 no_unroll_assignment10()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 no_unroll_assignment11()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 make_new_branches_loop_cached()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 make_new_branches_loop_uncached()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 make_new_branches_loop_uncached2()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 escape_before_loop_no_unroll1()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 escape_before_loop_no_unroll2()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 escape_before_loop_no_unroll3()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 nested_outer_unrolled()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 nested_inner_unrolled()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 nested_both_unrolled()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 simple_known_bound_loop()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 simple_unknown_bound_loop()347int simple_unknown_bound_loop() { 348 for (int i = 2; i < getNum(); i++) { 349 #ifdef DFS 350 clang_analyzer_numTimesReached(); // expected-warning {{16}} 351 #else 352 clang_analyzer_numTimesReached(); // expected-warning {{8}} 353 #endif 354 } 355 return 0; 356 } 357 nested_inlined_unroll1()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 nested_inlined_no_unroll1()368int nested_inlined_no_unroll1() { 369 int k; 370 for (int i = 0; i < 9; i++) { 371 #ifdef DFS 372 clang_analyzer_numTimesReached(); // expected-warning {{18}} 373 #else 374 clang_analyzer_numTimesReached(); // expected-warning {{14}} 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 recursion_unroll1(bool b)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 recursion_unroll2(bool b)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 recursion_unroll3(bool b)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 recursion_unroll4(bool b)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 loop_exit_while_empty_loop_stack()435int loop_exit_while_empty_loop_stack() { 436 if (getNum()) 437 for (int i = 1; i < 8; i++) 438 ; 439 return 0; 440 } 441 num_steps_on_limit()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 num_steps_over_limit1()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 num_steps_on_limit2()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 num_steps_over_limit2()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 num_steps_on_limit3()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 num_steps_over_limit3()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 pr34943()497void pr34943() { 498 for (int i = 0; i < 6L; ++i) { 499 clang_analyzer_numTimesReached(); // expected-warning {{6}} 500 } 501 } 502 parm_by_value_as_loop_counter(int i)503void parm_by_value_as_loop_counter(int i) { 504 for (i = 0; i < 10; ++i) { 505 clang_analyzer_numTimesReached(); // expected-warning {{10}} 506 } 507 } 508 parm_by_ref_as_loop_counter(int & i)509void parm_by_ref_as_loop_counter(int &i) { 510 for (i = 0; i < 10; ++i) { 511 clang_analyzer_numTimesReached(); // expected-warning {{4}} 512 } 513 } 514 capture_by_value_as_loop_counter()515void capture_by_value_as_loop_counter() { 516 int out = 0; 517 auto l = [i = out]() mutable { 518 for (i = 0; i < 10; ++i) { 519 clang_analyzer_numTimesReached(); // expected-warning {{10}} 520 } 521 }; 522 } 523 capture_by_ref_as_loop_counter()524void capture_by_ref_as_loop_counter() { 525 int out = 0; 526 auto l = [&i = out]() { 527 for (i = 0; i < 10; ++i) { 528 clang_analyzer_numTimesReached(); // expected-warning {{4}} 529 } 530 }; 531 } 532 capture_implicitly_by_value_as_loop_counter()533void capture_implicitly_by_value_as_loop_counter() { 534 int i = 0; 535 auto l = [=]() mutable { 536 for (i = 0; i < 10; ++i) { 537 clang_analyzer_numTimesReached(); // expected-warning {{10}} 538 } 539 }; 540 } 541 capture_implicitly_by_ref_as_loop_counter()542void capture_implicitly_by_ref_as_loop_counter() { 543 int i = 0; 544 auto l = [&]() mutable { 545 for (i = 0; i < 10; ++i) { 546 clang_analyzer_numTimesReached(); // expected-warning {{4}} 547 } 548 }; 549 } 550