1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s 2*67e74705SXin Li 3*67e74705SXin Li void clang_analyzer_eval(int); 4*67e74705SXin Li void clang_analyzer_warnIfReached(); 5*67e74705SXin Li 6*67e74705SXin Li typedef __typeof(sizeof(int)) size_t; 7*67e74705SXin Li void *malloc(size_t); 8*67e74705SXin Li void free(void *); 9*67e74705SXin Li loop_which_iterates_limit_times_not_widened()10*67e74705SXin Livoid loop_which_iterates_limit_times_not_widened() { 11*67e74705SXin Li int i; 12*67e74705SXin Li int x = 1; 13*67e74705SXin Li // Check loop isn't widened by checking x isn't invalidated 14*67e74705SXin Li for (i = 0; i < 1; ++i) {} 15*67e74705SXin Li clang_analyzer_eval(x == 1); // expected-warning {{TRUE}} 16*67e74705SXin Li for (i = 0; i < 2; ++i) {} 17*67e74705SXin Li clang_analyzer_eval(x == 1); // expected-warning {{TRUE}} 18*67e74705SXin Li for (i = 0; i < 3; ++i) {} 19*67e74705SXin Li // FIXME loss of precision as a result of evaluating the widened loop body 20*67e74705SXin Li // *instead* of the last iteration. 21*67e74705SXin Li clang_analyzer_eval(x == 1); // expected-warning {{UNKNOWN}} 22*67e74705SXin Li } 23*67e74705SXin Li 24*67e74705SXin Li int a_global; 25*67e74705SXin Li loop_evaluated_before_widening()26*67e74705SXin Livoid loop_evaluated_before_widening() { 27*67e74705SXin Li int i; 28*67e74705SXin Li a_global = 1; 29*67e74705SXin Li for (i = 0; i < 10; ++i) { 30*67e74705SXin Li if (i == 2) { 31*67e74705SXin Li // True before widening then unknown after. 32*67e74705SXin Li clang_analyzer_eval(a_global == 1); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}} 33*67e74705SXin Li } 34*67e74705SXin Li } 35*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 36*67e74705SXin Li } 37*67e74705SXin Li warnings_after_loop()38*67e74705SXin Livoid warnings_after_loop() { 39*67e74705SXin Li int i; 40*67e74705SXin Li for (i = 0; i < 10; ++i) {} 41*67e74705SXin Li char *m = (char*)malloc(12); 42*67e74705SXin Li } // expected-warning {{Potential leak of memory pointed to by 'm'}} 43*67e74705SXin Li for_loop_exits()44*67e74705SXin Livoid for_loop_exits() { 45*67e74705SXin Li int i; 46*67e74705SXin Li for (i = 0; i < 10; ++i) {} 47*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 48*67e74705SXin Li } 49*67e74705SXin Li while_loop_exits()50*67e74705SXin Livoid while_loop_exits() { 51*67e74705SXin Li int i = 0; 52*67e74705SXin Li while (i < 10) {++i;} 53*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 54*67e74705SXin Li } 55*67e74705SXin Li do_while_loop_exits()56*67e74705SXin Livoid do_while_loop_exits() { 57*67e74705SXin Li int i = 0; 58*67e74705SXin Li do {++i;} while (i < 10); 59*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 60*67e74705SXin Li } 61*67e74705SXin Li loop_body_is_widened()62*67e74705SXin Livoid loop_body_is_widened() { 63*67e74705SXin Li int i = 0; 64*67e74705SXin Li while (i < 100) { 65*67e74705SXin Li if (i > 10) { 66*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 67*67e74705SXin Li } 68*67e74705SXin Li ++i; 69*67e74705SXin Li } 70*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 71*67e74705SXin Li } 72*67e74705SXin Li invariably_infinite_loop()73*67e74705SXin Livoid invariably_infinite_loop() { 74*67e74705SXin Li int i = 0; 75*67e74705SXin Li while (1) { ++i; } 76*67e74705SXin Li clang_analyzer_warnIfReached(); // no-warning 77*67e74705SXin Li } 78*67e74705SXin Li invariably_infinite_break_loop()79*67e74705SXin Livoid invariably_infinite_break_loop() { 80*67e74705SXin Li int i = 0; 81*67e74705SXin Li while (1) { 82*67e74705SXin Li ++i; 83*67e74705SXin Li int x = 1; 84*67e74705SXin Li if (!x) break; 85*67e74705SXin Li } 86*67e74705SXin Li clang_analyzer_warnIfReached(); // no-warning 87*67e74705SXin Li } 88*67e74705SXin Li reachable_break_loop()89*67e74705SXin Livoid reachable_break_loop() { 90*67e74705SXin Li int i = 0; 91*67e74705SXin Li while (1) { 92*67e74705SXin Li ++i; 93*67e74705SXin Li if (i == 100) break; 94*67e74705SXin Li } 95*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 96*67e74705SXin Li } 97*67e74705SXin Li condition_constrained_true_in_loop()98*67e74705SXin Livoid condition_constrained_true_in_loop() { 99*67e74705SXin Li int i = 0; 100*67e74705SXin Li while (i < 50) { 101*67e74705SXin Li clang_analyzer_eval(i < 50); // expected-warning {{TRUE}} 102*67e74705SXin Li ++i; 103*67e74705SXin Li } 104*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 105*67e74705SXin Li } 106*67e74705SXin Li condition_constrained_false_after_loop()107*67e74705SXin Livoid condition_constrained_false_after_loop() { 108*67e74705SXin Li int i = 0; 109*67e74705SXin Li while (i < 50) { 110*67e74705SXin Li ++i; 111*67e74705SXin Li } 112*67e74705SXin Li clang_analyzer_eval(i >= 50); // expected-warning {{TRUE}} 113*67e74705SXin Li clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 114*67e74705SXin Li } 115*67e74705SXin Li multiple_exit_test()116*67e74705SXin Livoid multiple_exit_test() { 117*67e74705SXin Li int x = 0; 118*67e74705SXin Li int i = 0; 119*67e74705SXin Li while (i < 50) { 120*67e74705SXin Li if (x) { 121*67e74705SXin Li i = 10; 122*67e74705SXin Li break; 123*67e74705SXin Li } 124*67e74705SXin Li ++i; 125*67e74705SXin Li } 126*67e74705SXin Li // Reachable by 'normal' exit 127*67e74705SXin Li if (i == 50) clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 128*67e74705SXin Li // Reachable by break point 129*67e74705SXin Li if (i == 10) clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 130*67e74705SXin Li // Not reachable 131*67e74705SXin Li if (i < 10) clang_analyzer_warnIfReached(); // no-warning 132*67e74705SXin Li if (i > 10 && i < 50) clang_analyzer_warnIfReached(); // no-warning 133*67e74705SXin Li } 134*67e74705SXin Li pointer_doesnt_leak_from_loop()135*67e74705SXin Livoid pointer_doesnt_leak_from_loop() { 136*67e74705SXin Li int *h_ptr = (int *) malloc(sizeof(int)); 137*67e74705SXin Li for (int i = 0; i < 2; ++i) {} 138*67e74705SXin Li for (int i = 0; i < 10; ++i) {} // no-warning 139*67e74705SXin Li free(h_ptr); 140*67e74705SXin Li } 141*67e74705SXin Li 142*67e74705SXin Li int g_global; 143*67e74705SXin Li unknown_after_loop(int s_arg)144*67e74705SXin Livoid unknown_after_loop(int s_arg) { 145*67e74705SXin Li g_global = 0; 146*67e74705SXin Li s_arg = 1; 147*67e74705SXin Li int s_local = 2; 148*67e74705SXin Li int *h_ptr = malloc(sizeof(int)); 149*67e74705SXin Li 150*67e74705SXin Li for (int i = 0; i < 10; ++i) {} 151*67e74705SXin Li 152*67e74705SXin Li clang_analyzer_eval(g_global); // expected-warning {{UNKNOWN}} 153*67e74705SXin Li clang_analyzer_eval(s_arg); // expected-warning {{UNKNOWN}} 154*67e74705SXin Li clang_analyzer_eval(s_local); // expected-warning {{UNKNOWN}} 155*67e74705SXin Li clang_analyzer_eval(h_ptr == 0); // expected-warning {{UNKNOWN}} 156*67e74705SXin Li free(h_ptr); 157*67e74705SXin Li } 158*67e74705SXin Li variable_bound_exiting_loops_widened(int x)159*67e74705SXin Livoid variable_bound_exiting_loops_widened(int x) { 160*67e74705SXin Li int i = 0; 161*67e74705SXin Li int t = 1; 162*67e74705SXin Li while (i < x) { 163*67e74705SXin Li ++i; 164*67e74705SXin Li } 165*67e74705SXin Li clang_analyzer_eval(t == 1); // expected-warning {{TRUE}} // expected-warning {{UNKNOWN}} 166*67e74705SXin Li } 167*67e74705SXin Li nested_loop_outer_widen()168*67e74705SXin Livoid nested_loop_outer_widen() { 169*67e74705SXin Li int i = 0, j = 0; 170*67e74705SXin Li for (i = 0; i < 10; i++) { 171*67e74705SXin Li clang_analyzer_eval(i < 10); // expected-warning {{TRUE}} 172*67e74705SXin Li for (j = 0; j < 2; j++) { 173*67e74705SXin Li clang_analyzer_eval(j < 2); // expected-warning {{TRUE}} 174*67e74705SXin Li } 175*67e74705SXin Li clang_analyzer_eval(j >= 2); // expected-warning {{TRUE}} 176*67e74705SXin Li } 177*67e74705SXin Li clang_analyzer_eval(i >= 10); // expected-warning {{TRUE}} 178*67e74705SXin Li } 179*67e74705SXin Li nested_loop_inner_widen()180*67e74705SXin Livoid nested_loop_inner_widen() { 181*67e74705SXin Li int i = 0, j = 0; 182*67e74705SXin Li for (i = 0; i < 2; i++) { 183*67e74705SXin Li clang_analyzer_eval(i < 2); // expected-warning {{TRUE}} 184*67e74705SXin Li for (j = 0; j < 10; j++) { 185*67e74705SXin Li clang_analyzer_eval(j < 10); // expected-warning {{TRUE}} 186*67e74705SXin Li } 187*67e74705SXin Li clang_analyzer_eval(j >= 10); // expected-warning {{TRUE}} 188*67e74705SXin Li } 189*67e74705SXin Li clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}} 190*67e74705SXin Li } 191