1// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -fsyntax-only -fblocks %s -verify 2 3typedef __typeof(sizeof(int)) size_t; 4void *malloc(size_t); 5 6int 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 11int test2() { 12 int x = 0; 13 return x; // no-warning 14} 15 16int test3() { 17 int x; 18 x = 0; 19 return x; // no-warning 20} 21 22int 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 28int 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 34int 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 40int 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 48int 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 58int test8(int y) { 59 int x; 60 if (y) 61 x = 1; 62 else 63 x = 0; 64 return x; 65} 66 67int 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 77int 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 85int 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 93void 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 97int test13() { 98 static int i; 99 return i; // no-warning 100} 101 102// Simply don't crash on this test case. 103void test14() { 104 const char *p = 0; 105 for (;;) {} 106} 107 108void test15() { 109 int x = x; // no-warning: signals intended lack of initialization. 110} 111 112int 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. 120char *test16_aux(); 121void test16() { 122 char *p = test16_aux(); 123 for (unsigned i = 0 ; i < 100 ; i++) 124 p[i] = 'a'; // no-warning 125} 126 127void 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 135int 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 143int test19_aux1(); 144int test19_aux2(); 145int test19_aux3(int *x); 146int 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 153int 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 160int 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 167int 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 174int 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. 185int 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 194float 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 199typedef int MyInt; 200MyInt 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(). 206int test27() { 207 struct test_27 { int x; } *y; 208 return sizeof(y->x); // no-warning 209} 210 211int 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 216void 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 221void test30() { 222 static int x; // no-warning 223 (void) ^{ (void) x; }; 224} 225 226void test31() { 227 __block int x; // no-warning 228 (void) ^{ (void) x; }; 229} 230 231int test32_x; 232void test32() { 233 (void) ^{ (void) test32_x; }; // no-warning 234} 235 236void test_33() { 237 int x; // no-warning 238 (void) x; 239} 240 241int 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. 248void test35(int x) { 249 __block int y = 0; 250 ^{ y = (x == 0); }(); 251} 252 253// Test handling of indirect goto. 254void 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 ||. 265int test37_a(); 266int test37_b(); 267int 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). 278int test38(int r, int x, int y) 279{ 280 int z; 281 return ((r < 0) || ((r == 0) && (x < y))); 282} 283 284int 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 291int 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 296int 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 303void test42() { 304 int a; 305 a = 30; // no-warning 306} 307 308void test43_aux(int x); 309void 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 315void 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 324int test45(int j) { 325 int x = 1, y = x + 1; 326 if (y) // no-warning 327 return x; 328 return y; 329} 330 331void 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 337void *test47(int *i) 338{ 339 return i ? : 0; // no-warning 340} 341 342void *test49(int *i) 343{ 344 int a; 345 return &a ? : i; // no-warning 346} 347 348void test50() 349{ 350 char c[1 ? : 2]; // no-warning 351} 352 353int 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. 363int 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 376void 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. 382extern int PR10379_g(); 383void 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. 397void 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. 403int 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. 412void 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. 425void 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; 434void 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 442struct { struct { void *p; } a; } test55 = { { &test55.a }}; // no-warning 443struct { struct { void *p; } a; } test56 = { { &(test56.a) }}; // no-warning 444 445void 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 455void 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}} 461skip_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 470typedef char jmp_buf[256]; 471extern int setjmp(jmp_buf env); // implicitly returns_twice 472 473void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn)); 474 475int 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 489int 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 496int compound_assign_2() { 497 int x; // expected-note {{initialize}} 498 return x += 1; // expected-warning {{variable 'x' is uninitialized}} 499} 500 501int compound_assign_3() { 502 int x; // expected-note {{initialize}} 503 x *= 0; // expected-warning {{variable 'x' is uninitialized}} 504 return x; 505} 506 507int self_init_in_cond(int *p) { 508 int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok 509 return n; 510} 511 512void test_analyzer_noreturn_aux() __attribute__((analyzer_noreturn)); 513 514void 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} 524void 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