1 // RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -fsyntax-only -fblocks %s -verify 2 3 typedef __typeof(sizeof(int)) size_t; 4 void *malloc(size_t); 5 6 int test1() { 7 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 8 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 9 } 10 11 int test2() { 12 int x = 0; 13 return x; // no-warning 14 } 15 16 int test3() { 17 int x; 18 x = 0; 19 return x; // no-warning 20 } 21 22 int test4() { 23 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 24 ++x; // expected-warning{{variable 'x' is uninitialized when used here}} 25 return x; 26 } 27 28 int test5() { 29 int x, y; // expected-note{{initialize the variable 'y' to silence this warning}} 30 x = y; // expected-warning{{variable 'y' is uninitialized when used here}} 31 return x; 32 } 33 34 int test6() { 35 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 36 x += 2; // expected-warning{{variable 'x' is uninitialized when used here}} 37 return x; 38 } 39 40 int test7(int y) { 41 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 42 if (y) // expected-warning{{variable 'x' is used uninitialized whenever 'if' condition is false}} \ 43 // expected-note{{remove the 'if' if its condition is always true}} 44 x = 1; 45 return x; // expected-note{{uninitialized use occurs here}} 46 } 47 48 int test7b(int y) { 49 int x = x; // expected-note{{variable 'x' is declared here}} 50 if (y) 51 x = 1; 52 // Warn with "may be uninitialized" here (not "is sometimes uninitialized"), 53 // since the self-initialization is intended to suppress a -Wuninitialized 54 // warning. 55 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 56 } 57 58 int test8(int y) { 59 int x; 60 if (y) 61 x = 1; 62 else 63 x = 0; 64 return x; 65 } 66 67 int test9(int n) { 68 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 69 for (unsigned i = 0 ; i < n; ++i) { 70 if (i == n - 1) 71 break; 72 x = 1; 73 } 74 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 75 } 76 77 int test10(unsigned n) { 78 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 79 for (unsigned i = 0 ; i < n; ++i) { 80 x = 1; 81 } 82 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 83 } 84 85 int test11(unsigned n) { 86 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 87 for (unsigned i = 0 ; i <= n; ++i) { 88 x = 1; 89 } 90 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 91 } 92 93 void test12(unsigned n) { 94 for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is uninitialized when used here}} expected-note{{initialize the variable 'i' to silence this warning}} 95 } 96 97 int test13() { 98 static int i; 99 return i; // no-warning 100 } 101 102 // Simply don't crash on this test case. 103 void test14() { 104 const char *p = 0; 105 for (;;) {} 106 } 107 108 void test15() { 109 int x = x; // no-warning: signals intended lack of initialization. 110 } 111 112 int test15b() { 113 // Warn here with the self-init, since it does result in a use of 114 // an unintialized variable and this is the root cause. 115 int x = x; // expected-warning {{variable 'x' is uninitialized when used within its own initialization}} 116 return x; 117 } 118 119 // Don't warn in the following example; shows dataflow confluence. 120 char *test16_aux(); 121 void test16() { 122 char *p = test16_aux(); 123 for (unsigned i = 0 ; i < 100 ; i++) 124 p[i] = 'a'; // no-warning 125 } 126 127 void test17() { 128 // Don't warn multiple times about the same uninitialized variable 129 // along the same path. 130 int *x; // expected-note{{initialize the variable 'x' to silence this warning}} 131 *x = 1; // expected-warning{{variable 'x' is uninitialized when used here}} 132 *x = 1; // no-warning 133 } 134 135 int test18(int x, int y) { 136 int z; 137 if (x && y && (z = 1)) { 138 return z; // no-warning 139 } 140 return 0; 141 } 142 143 int test19_aux1(); 144 int test19_aux2(); 145 int test19_aux3(int *x); 146 int test19() { 147 int z; 148 if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z)) 149 return z; // no-warning 150 return 0; 151 } 152 153 int test20() { 154 int z; // expected-note{{initialize the variable 'z' to silence this warning}} 155 if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}} 156 return z; // expected-note {{uninitialized use occurs here}} 157 return 0; 158 } 159 160 int test21(int x, int y) { 161 int z; // expected-note{{initialize the variable 'z' to silence this warning}} 162 if ((x && y) || test19_aux3(&z) || test19_aux2()) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}} 163 return z; // expected-note {{uninitialized use occurs here}} 164 return 0; 165 } 166 167 int test22() { 168 int z; 169 while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z)) 170 return z; // no-warning 171 return 0; 172 } 173 174 int test23() { 175 int z; 176 for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; ) 177 return z; // no-warning 178 return 0; 179 } 180 181 // The basic uninitialized value analysis doesn't have enough path-sensitivity 182 // to catch initializations relying on control-dependencies spanning multiple 183 // conditionals. This possibly can be handled by making the CFG itself 184 // represent such control-dependencies, but it is a niche case. 185 int test24(int flag) { 186 unsigned val; // expected-note{{initialize the variable 'val' to silence this warning}} 187 if (flag) 188 val = 1; 189 if (!flag) 190 val = 1; 191 return val; // expected-warning{{variable 'val' may be uninitialized when used here}} 192 } 193 194 float test25() { 195 float x; // expected-note{{initialize the variable 'x' to silence this warning}} 196 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 197 } 198 199 typedef int MyInt; 200 MyInt test26() { 201 MyInt x; // expected-note{{initialize the variable 'x' to silence this warning}} 202 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 203 } 204 205 // Test handling of sizeof(). 206 int test27() { 207 struct test_27 { int x; } *y; 208 return sizeof(y->x); // no-warning 209 } 210 211 int test28() { 212 int len; // expected-note{{initialize the variable 'len' to silence this warning}} 213 return sizeof(int[len]); // expected-warning{{variable 'len' is uninitialized when used here}} 214 } 215 216 void test29() { 217 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 218 (void) ^{ (void) x; }; // expected-warning{{variable 'x' is uninitialized when captured by block}} 219 } 220 221 void test30() { 222 static int x; // no-warning 223 (void) ^{ (void) x; }; 224 } 225 226 void test31() { 227 __block int x; // no-warning 228 (void) ^{ (void) x; }; 229 } 230 231 int test32_x; 232 void test32() { 233 (void) ^{ (void) test32_x; }; // no-warning 234 } 235 236 void test_33() { 237 int x; // no-warning 238 (void) x; 239 } 240 241 int test_34() { 242 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 243 (void) x; 244 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 245 } 246 247 // Test that this case doesn't crash. 248 void test35(int x) { 249 __block int y = 0; 250 ^{ y = (x == 0); }(); 251 } 252 253 // Test handling of indirect goto. 254 void test36() 255 { 256 void **pc; // expected-note{{initialize the variable 'pc' to silence this warning}} 257 void *dummy[] = { &&L1, &&L2 }; 258 L1: 259 goto *pc; // expected-warning{{variable 'pc' is uninitialized when used here}} 260 L2: 261 goto *pc; 262 } 263 264 // Test && nested in ||. 265 int test37_a(); 266 int test37_b(); 267 int test37() 268 { 269 int identifier; 270 if ((test37_a() && (identifier = 1)) || 271 (test37_b() && (identifier = 2))) { 272 return identifier; // no-warning 273 } 274 return 0; 275 } 276 277 // Test merging of path-specific dataflow values (without asserting). 278 int test38(int r, int x, int y) 279 { 280 int z; 281 return ((r < 0) || ((r == 0) && (x < y))); 282 } 283 284 int test39(int x) { 285 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 286 int z = x + y; // expected-warning {{variable 'y' is uninitialized when used here}} 287 return z; 288 } 289 290 291 int test40(int x) { 292 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 293 return x ? 1 : y; // expected-warning {{variable 'y' is uninitialized when used here}} 294 } 295 296 int test41(int x) { 297 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 298 if (x) y = 1; // expected-warning{{variable 'y' is used uninitialized whenever 'if' condition is false}} \ 299 // expected-note{{remove the 'if' if its condition is always true}} 300 return y; // expected-note{{uninitialized use occurs here}} 301 } 302 303 void test42() { 304 int a; 305 a = 30; // no-warning 306 } 307 308 void test43_aux(int x); 309 void test43(int i) { 310 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 311 for (i = 0 ; i < 10; i++) 312 test43_aux(x++); // expected-warning {{variable 'x' is uninitialized when used here}} 313 } 314 315 void test44(int i) { 316 int x = i; 317 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 318 for (i = 0; i < 10; i++ ) { 319 test43_aux(x++); // no-warning 320 x += y; // expected-warning {{variable 'y' is uninitialized when used here}} 321 } 322 } 323 324 int test45(int j) { 325 int x = 1, y = x + 1; 326 if (y) // no-warning 327 return x; 328 return y; 329 } 330 331 void test46() 332 { 333 int i; // expected-note{{initialize the variable 'i' to silence this warning}} 334 int j = i ? : 1; // expected-warning {{variable 'i' is uninitialized when used here}} 335 } 336 337 void *test47(int *i) 338 { 339 return i ? : 0; // no-warning 340 } 341 342 void *test49(int *i) 343 { 344 int a; 345 return &a ? : i; // no-warning 346 } 347 348 void test50() 349 { 350 char c[1 ? : 2]; // no-warning 351 } 352 353 int test51(void) 354 { 355 __block int a; 356 ^(void) { 357 a = 42; 358 }(); 359 return a; // no-warning 360 } 361 362 // FIXME: This is a false positive, but it tests logical operations in switch statements. 363 int test52(int a, int b) { 364 int x; // expected-note {{initialize the variable 'x' to silence this warning}} 365 switch (a || b) { // expected-warning {{switch condition has boolean value}} 366 case 0: 367 x = 1; 368 break; 369 case 1: 370 x = 2; 371 break; 372 } 373 return x; // expected-warning {{variable 'x' may be uninitialized when used here}} 374 } 375 376 void test53() { 377 int x; // expected-note {{initialize the variable 'x' to silence this warning}} 378 int y = (x); // expected-warning {{variable 'x' is uninitialized when used here}} 379 } 380 381 // This CFG caused the uninitialized values warning to inf-loop. 382 extern int PR10379_g(); 383 void PR10379_f(int *len) { 384 int new_len; // expected-note{{initialize the variable 'new_len' to silence this warning}} 385 for (int i = 0; i < 42 && PR10379_g() == 0; i++) { 386 if (PR10379_g() == 1) 387 continue; 388 if (PR10379_g() == 2) 389 PR10379_f(&new_len); 390 else if (PR10379_g() == 3) 391 PR10379_f(&new_len); 392 *len += new_len; // expected-warning {{variable 'new_len' may be uninitialized when used here}} 393 } 394 } 395 396 // Test that sizeof(VLA) doesn't trigger a warning. 397 void test_vla_sizeof(int x) { 398 double (*memory)[2][x] = malloc(sizeof(*memory)); // no-warning 399 } 400 401 // Test absurd case of deadcode + use of blocks. This previously was a false positive 402 // due to an analysis bug. 403 int test_block_and_dead_code() { 404 __block int x; 405 ^{ x = 1; }(); 406 if (0) 407 return x; 408 return x; // no-warning 409 } 410 411 // This previously triggered an infinite loop in the analysis. 412 void PR11069(int a, int b) { 413 unsigned long flags; 414 for (;;) { 415 if (a && !b) 416 break; 417 } 418 for (;;) { 419 // This does not trigger a warning because it isn't a real use. 420 (void)(flags); // no-warning 421 } 422 } 423 424 // Test uninitialized value used in loop condition. 425 void rdar9432305(float *P) { 426 int i; // expected-note {{initialize the variable 'i' to silence this warning}} 427 for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}} 428 P[i] = 0.0f; 429 } 430 431 // Test that fixits are not emitted inside macros. 432 #define UNINIT(T, x, y) T x; T y = x; 433 #define ASSIGN(T, x, y) T y = x; 434 void test54() { 435 UNINIT(int, a, b); // expected-warning {{variable 'a' is uninitialized when used here}} \ 436 // expected-note {{variable 'a' is declared here}} 437 int c; // expected-note {{initialize the variable 'c' to silence this warning}} 438 ASSIGN(int, c, d); // expected-warning {{variable 'c' is uninitialized when used here}} 439 } 440 441 // Taking the address is fine 442 struct { struct { void *p; } a; } test55 = { { &test55.a }}; // no-warning 443 struct { struct { void *p; } a; } test56 = { { &(test56.a) }}; // no-warning 444 445 void uninit_in_loop() { 446 int produce(void); 447 void consume(int); 448 for (int n = 0; n < 100; ++n) { 449 int k; // expected-note {{initialize}} 450 consume(k); // expected-warning {{variable 'k' is uninitialized}} 451 k = produce(); 452 } 453 } 454 455 void uninit_in_loop_goto() { 456 int produce(void); 457 void consume(int); 458 for (int n = 0; n < 100; ++n) { 459 goto skip_decl; 460 int k; // expected-note {{initialize}} 461 skip_decl: 462 // FIXME: This should produce the 'is uninitialized' diagnostic, but we 463 // don't have enough information in the CFG to easily tell that the 464 // variable's scope has been left and re-entered. 465 consume(k); // expected-warning {{variable 'k' may be uninitialized}} 466 k = produce(); 467 } 468 } 469 470 typedef char jmp_buf[256]; 471 extern int setjmp(jmp_buf env); // implicitly returns_twice 472 473 void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn)); 474 475 int returns_twice() { 476 int a; // expected-note {{initialize}} 477 if (!a) { // expected-warning {{variable 'a' is uninitialized}} 478 jmp_buf env; 479 int b; 480 if (setjmp(env) == 0) { 481 do_stuff_and_longjmp(env, &b); 482 } else { 483 a = b; // no warning 484 } 485 } 486 return a; 487 } 488 489 int compound_assign(int *arr, int n) { 490 int sum; // expected-note {{initialize}} 491 for (int i = 0; i < n; ++i) 492 sum += arr[i]; // expected-warning {{variable 'sum' is uninitialized}} 493 return sum / n; 494 } 495 496 int compound_assign_2() { 497 int x; // expected-note {{initialize}} 498 return x += 1; // expected-warning {{variable 'x' is uninitialized}} 499 } 500 501 int compound_assign_3() { 502 int x; // expected-note {{initialize}} 503 x *= 0; // expected-warning {{variable 'x' is uninitialized}} 504 return x; 505 } 506 507 int self_init_in_cond(int *p) { 508 int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok 509 return n; 510 } 511 512 void test_analyzer_noreturn_aux() __attribute__((analyzer_noreturn)); 513 514 void test_analyzer_noreturn(int y) { 515 int x; // expected-note {{initialize the variable 'x' to silence this warning}} 516 if (y) { 517 test_analyzer_noreturn_aux(); 518 ++x; // no-warning 519 } 520 else { 521 ++x; // expected-warning {{variable 'x' is uninitialized when used here}} 522 } 523 } 524 void test_analyzer_noreturn_2(int y) { 525 int x; 526 if (y) { 527 test_analyzer_noreturn_aux(); 528 } 529 else { 530 x = 1; 531 } 532 ++x; // no-warning 533 } 534