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
4 void clang_analyzer_numTimesReached();
5 void clang_analyzer_warnIfReached();
10 int simple_unroll1() {
13 for (int i
= 0; i
< 9; i
++) {
14 clang_analyzer_numTimesReached(); // expected-warning {{9}}
17 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
21 int simple_unroll2() {
25 for (i
= 0; i
< 9; i
++) {
26 clang_analyzer_numTimesReached(); // expected-warning {{9}}
30 for (int j
= 0; j
<= 9; ++j
) {
31 clang_analyzer_numTimesReached(); // expected-warning {{10}}
35 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
39 int simple_unroll3_unsigned() {
42 for (unsigned i
= 0; i
< 9; i
++) {
43 clang_analyzer_numTimesReached(); // expected-warning {{9}}
46 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
50 int simple_unroll4_unsigned() {
54 for (i
= (0); i
< 9; i
++) {
55 clang_analyzer_numTimesReached(); // expected-warning {{9}}
58 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
62 int simple_no_unroll1() {
65 for (int i
= 0; i
< 9; i
++) {
66 clang_analyzer_numTimesReached(); // expected-warning {{4}}
70 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
74 int simple_no_unroll2() {
78 for (i
= 0; i
< 9; i
++) {
79 clang_analyzer_numTimesReached(); // expected-warning {{4}}
83 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
87 int simple_no_unroll3() {
90 for (int i
= 0; i
< 9; i
++) {
91 clang_analyzer_numTimesReached(); // expected-warning {{4}}
95 int b
= 22 / (k
- 42); // no-warning
99 int simple_no_unroll4() {
103 for (i
= 0; i
< 9; i
++) {
104 clang_analyzer_numTimesReached(); // expected-warning {{4}}
108 int b
= 22 / (k
- 42); // no-warning
112 int simple_no_unroll5() {
116 for (i
= 0; i
< 9; i
++) {
117 clang_analyzer_numTimesReached(); // expected-warning {{4}}
121 int b
= 22 / (k
- 42); // no-warning
125 int no_unroll_assignment() {
126 for (int i
= 0; i
< 9; i
++) {
128 clang_analyzer_numTimesReached(); // expected-warning {{4}}
133 int no_unroll_assignment2() {
134 for (int i
= 0; i
< 9; i
++) {
136 clang_analyzer_numTimesReached(); // expected-warning {{4}}
141 int no_unroll_assignment3() {
142 for (int i
= 128; i
> 0; i
--) {
144 clang_analyzer_numTimesReached(); // expected-warning {{4}}
149 int no_unroll_assignment4() {
150 for (int i
= 0; i
< 9; i
++) {
152 clang_analyzer_numTimesReached(); // expected-warning {{4}}
157 int no_unroll_assignment5() {
158 for (int i
= 0; i
< 9; i
++) {
160 clang_analyzer_numTimesReached(); // expected-warning {{4}}
165 int no_unroll_assignment6() {
166 for (int i
= 128; i
> 0; i
--) {
168 clang_analyzer_numTimesReached(); // expected-warning {{4}}
173 int no_unroll_assignment7() {
174 for (int i
= 0; i
< 512; i
++) {
176 clang_analyzer_numTimesReached(); // expected-warning {{4}}
181 int no_unroll_assignment8() {
182 for (int i
= 0; i
< 9; i
++) {
184 clang_analyzer_numTimesReached(); // expected-warning {{4}}
189 int no_unroll_assignment9() {
190 for (int i
= 0; i
< 9; i
++) {
192 clang_analyzer_numTimesReached(); // expected-warning {{4}}
197 int no_unroll_assignment10() {
198 for (int i
= 0; i
< 9; i
++) {
200 clang_analyzer_numTimesReached(); // expected-warning {{4}}
205 int no_unroll_assignment11() {
206 for (int i
= 0; i
< 9; i
++) {
208 clang_analyzer_numTimesReached(); // expected-warning {{4}}
213 int make_new_branches_loop_cached() {
214 for (int i
= 0; i
< 8; i
++) {
215 clang_analyzer_numTimesReached(); // expected-warning {{4}}
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.
221 clang_analyzer_warnIfReached(); // no-warning
225 int make_new_branches_loop_uncached() {
227 for (int i
= 0; i
< 8; i
++) {
228 clang_analyzer_numTimesReached(); // expected-warning {{10}}
233 clang_analyzer_warnIfReached(); // no-warning
237 int make_new_branches_loop_uncached2() {
239 for (int i
= 0; i
< 8; i
++) {
240 clang_analyzer_numTimesReached(); // expected-warning {{10}}
244 (void)&i
; // This ensures that the loop won't be unrolled.
246 clang_analyzer_warnIfReached(); // no-warning
251 int escape_before_loop_no_unroll1() {
256 for (i
= 0; i
< 9; i
++) {
257 clang_analyzer_numTimesReached(); // expected-warning {{4}}
260 int b
= 22 / (k
- 42); // no-warning
264 int escape_before_loop_no_unroll2() {
269 for (i
= 0; i
< 9; i
++) {
270 clang_analyzer_numTimesReached(); // expected-warning {{4}}
273 int b
= 22 / (k
- 42); // no-warning
277 int escape_before_loop_no_unroll3() {
282 for (i
= 0; i
< 9; i
++) {
283 clang_analyzer_numTimesReached(); // expected-warning {{4}}
286 int b
= 22 / (k
- 42); // no-warning
290 int nested_outer_unrolled() {
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}}
299 (void)&j
; // ensures that the inner loop won't be unrolled
303 int b
= 22 / (k
- 42); // no-warning
307 int nested_inner_unrolled() {
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}}
319 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
323 int nested_both_unrolled() {
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}}
335 int b
= 22 / (k
- 42); // expected-warning {{Division by zero}}
339 int 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}}
347 int simple_unknown_bound_loop() {
348 for (int i
= 2; i
< getNum(); i
++) {
350 clang_analyzer_numTimesReached(); // expected-warning {{16}}
352 clang_analyzer_numTimesReached(); // expected-warning {{8}}
358 int nested_inlined_unroll1() {
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
364 int a
= 22 / k
; // expected-warning {{Division by zero}}
368 int nested_inlined_no_unroll1() {
370 for (int i
= 0; i
< 9; i
++) {
372 clang_analyzer_numTimesReached(); // expected-warning {{18}}
374 clang_analyzer_numTimesReached(); // expected-warning {{14}}
376 k
= simple_unknown_bound_loop(); // reevaluation without inlining, splits the state as well
378 int a
= 22 / k
; // no-warning
382 int recursion_unroll1(bool b
) {
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}}
391 int a
= 22 / k
; // no-warning
395 int recursion_unroll2(bool b
) {
397 for (int i
= 0; i
< 5; i
++) {
398 clang_analyzer_numTimesReached(); // expected-warning {{9}}
400 recursion_unroll2(false);
401 clang_analyzer_numTimesReached(); // expected-warning {{9}}
403 int a
= 22 / k
; // expected-warning {{Division by zero}}
407 int recursion_unroll3(bool b
) {
409 for (int i
= 0; i
< 5; i
++) {
410 clang_analyzer_numTimesReached(); // expected-warning {{10}}
412 recursion_unroll3(false);
415 clang_analyzer_numTimesReached(); // expected-warning {{10}}
421 int recursion_unroll4(bool b
) {
423 for (int i
= 0; i
< 5; i
++) {
424 clang_analyzer_numTimesReached(); // expected-warning {{13}}
426 recursion_unroll4(false);
429 clang_analyzer_numTimesReached(); // expected-warning {{13}}
435 int loop_exit_while_empty_loop_stack() {
437 for (int i
= 1; i
< 8; i
++)
442 int num_steps_on_limit() {
443 for (int i
= 0; i
< 128; i
++) {
444 clang_analyzer_numTimesReached(); // expected-warning {{128}}
446 clang_analyzer_numTimesReached(); // expected-warning {{1}}
450 int num_steps_over_limit1() {
451 for (int i
= 0; i
< 129; i
++) {
452 clang_analyzer_numTimesReached(); // expected-warning {{4}}
457 int 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}}
466 int 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}}
476 int 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}}
486 int 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}}
498 for (int i
= 0; i
< 6L; ++i
) {
499 clang_analyzer_numTimesReached(); // expected-warning {{6}}
503 void parm_by_value_as_loop_counter(int i
) {
504 for (i
= 0; i
< 10; ++i
) {
505 clang_analyzer_numTimesReached(); // expected-warning {{10}}
509 void parm_by_ref_as_loop_counter(int &i
) {
510 for (i
= 0; i
< 10; ++i
) {
511 clang_analyzer_numTimesReached(); // expected-warning {{4}}
515 void capture_by_value_as_loop_counter() {
517 auto l
= [i
= out
]() mutable {
518 for (i
= 0; i
< 10; ++i
) {
519 clang_analyzer_numTimesReached(); // expected-warning {{10}}
524 void capture_by_ref_as_loop_counter() {
526 auto l
= [&i
= out
]() {
527 for (i
= 0; i
< 10; ++i
) {
528 clang_analyzer_numTimesReached(); // expected-warning {{4}}
533 void capture_implicitly_by_value_as_loop_counter() {
535 auto l
= [=]() mutable {
536 for (i
= 0; i
< 10; ++i
) {
537 clang_analyzer_numTimesReached(); // expected-warning {{10}}
542 void capture_implicitly_by_ref_as_loop_counter() {
544 auto l
= [&]() mutable {
545 for (i
= 0; i
< 10; ++i
) {
546 clang_analyzer_numTimesReached(); // expected-warning {{4}}
552 void test_escaping_on_var_before_switch_case_no_crash(int c
) {
553 // https://github.com/llvm/llvm-project/issues/68819
555 int i
; // no-crash: The declaration of `i` is found here.
557 for (i
= 0; i
< 16; i
++) {}