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