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