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