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) 43 x = 1; 44 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 45} 46 47int test7b(int y) { 48 int x = x; // expected-note{{variable 'x' is declared here}} 49 if (y) 50 x = 1; 51 // Warn with "may be uninitialized" here (not "is uninitialized"), since the 52 // self-initialization is intended to suppress a -Wuninitialized warning. 53 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 54} 55 56int test8(int y) { 57 int x; 58 if (y) 59 x = 1; 60 else 61 x = 0; 62 return x; 63} 64 65int test9(int n) { 66 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 67 for (unsigned i = 0 ; i < n; ++i) { 68 if (i == n - 1) 69 break; 70 x = 1; 71 } 72 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 73} 74 75int test10(unsigned n) { 76 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 77 for (unsigned i = 0 ; i < n; ++i) { 78 x = 1; 79 } 80 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 81} 82 83int test11(unsigned n) { 84 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 85 for (unsigned i = 0 ; i <= n; ++i) { 86 x = 1; 87 } 88 return x; // expected-warning{{variable 'x' may be uninitialized when used here}} 89} 90 91void test12(unsigned n) { 92 for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is uninitialized when used here}} expected-note{{initialize the variable 'i' to silence this warning}} 93} 94 95int test13() { 96 static int i; 97 return i; // no-warning 98} 99 100// Simply don't crash on this test case. 101void test14() { 102 const char *p = 0; 103 for (;;) {} 104} 105 106void test15() { 107 int x = x; // no-warning: signals intended lack of initialization. 108} 109 110int test15b() { 111 // Warn here with the self-init, since it does result in a use of 112 // an unintialized variable and this is the root cause. 113 int x = x; // expected-warning {{variable 'x' is uninitialized when used within its own initialization}} 114 return x; 115} 116 117// Don't warn in the following example; shows dataflow confluence. 118char *test16_aux(); 119void test16() { 120 char *p = test16_aux(); 121 for (unsigned i = 0 ; i < 100 ; i++) 122 p[i] = 'a'; // no-warning 123} 124 125void test17() { 126 // Don't warn multiple times about the same uninitialized variable 127 // along the same path. 128 int *x; // expected-note{{initialize the variable 'x' to silence this warning}} 129 *x = 1; // expected-warning{{variable 'x' is uninitialized when used here}} 130 *x = 1; // no-warning 131} 132 133int test18(int x, int y) { 134 int z; 135 if (x && y && (z = 1)) { 136 return z; // no-warning 137 } 138 return 0; 139} 140 141int test19_aux1(); 142int test19_aux2(); 143int test19_aux3(int *x); 144int test19() { 145 int z; 146 if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z)) 147 return z; // no-warning 148 return 0; 149} 150 151int test20() { 152 int z; // expected-note{{initialize the variable 'z' to silence this warning}} 153 if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) 154 return z; // expected-warning{{variable 'z' may be uninitialized when used here}} 155 return 0; 156} 157 158int test21(int x, int y) { 159 int z; // expected-note{{initialize the variable 'z' to silence this warning}} 160 if ((x && y) || test19_aux3(&z) || test19_aux2()) 161 return z; // expected-warning{{variable 'z' may be uninitialized when used here}} 162 return 0; 163} 164 165int test22() { 166 int z; 167 while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z)) 168 return z; // no-warning 169 return 0; 170} 171 172int test23() { 173 int z; 174 for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; ) 175 return z; // no-warning 176 return 0; 177} 178 179// The basic uninitialized value analysis doesn't have enough path-sensitivity 180// to catch initializations relying on control-dependencies spanning multiple 181// conditionals. This possibly can be handled by making the CFG itself 182// represent such control-dependencies, but it is a niche case. 183int test24(int flag) { 184 unsigned val; // expected-note{{initialize the variable 'val' to silence this warning}} 185 if (flag) 186 val = 1; 187 if (!flag) 188 val = 1; 189 return val; // expected-warning{{variable 'val' may be uninitialized when used here}} 190} 191 192float test25() { 193 float x; // expected-note{{initialize the variable 'x' to silence this warning}} 194 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 195} 196 197typedef int MyInt; 198MyInt test26() { 199 MyInt x; // expected-note{{initialize the variable 'x' to silence this warning}} 200 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 201} 202 203// Test handling of sizeof(). 204int test27() { 205 struct test_27 { int x; } *y; 206 return sizeof(y->x); // no-warning 207} 208 209int test28() { 210 int len; // expected-note{{initialize the variable 'len' to silence this warning}} 211 return sizeof(int[len]); // expected-warning{{variable 'len' is uninitialized when used here}} 212} 213 214void test29() { 215 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 216 (void) ^{ (void) x; }; // expected-warning{{variable 'x' is uninitialized when captured by block}} 217} 218 219void test30() { 220 static int x; // no-warning 221 (void) ^{ (void) x; }; 222} 223 224void test31() { 225 __block int x; // no-warning 226 (void) ^{ (void) x; }; 227} 228 229int test32_x; 230void test32() { 231 (void) ^{ (void) test32_x; }; // no-warning 232} 233 234void test_33() { 235 int x; // no-warning 236 (void) x; 237} 238 239int test_34() { 240 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 241 (void) x; 242 return x; // expected-warning{{variable 'x' is uninitialized when used here}} 243} 244 245// Test that this case doesn't crash. 246void test35(int x) { 247 __block int y = 0; 248 ^{ y = (x == 0); }(); 249} 250 251// Test handling of indirect goto. 252void test36() 253{ 254 void **pc; // expected-note{{initialize the variable 'pc' to silence this warning}} 255 void *dummy[] = { &&L1, &&L2 }; 256 L1: 257 goto *pc; // expected-warning{{variable 'pc' is uninitialized when used here}} 258 L2: 259 goto *pc; 260} 261 262// Test && nested in ||. 263int test37_a(); 264int test37_b(); 265int test37() 266{ 267 int identifier; 268 if ((test37_a() && (identifier = 1)) || 269 (test37_b() && (identifier = 2))) { 270 return identifier; // no-warning 271 } 272 return 0; 273} 274 275// Test merging of path-specific dataflow values (without asserting). 276int test38(int r, int x, int y) 277{ 278 int z; 279 return ((r < 0) || ((r == 0) && (x < y))); 280} 281 282int test39(int x) { 283 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 284 int z = x + y; // expected-warning {{variable 'y' is uninitialized when used here}} 285 return z; 286} 287 288 289int test40(int x) { 290 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 291 return x ? 1 : y; // expected-warning {{variable 'y' is uninitialized when used here}} 292} 293 294int test41(int x) { 295 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 296 if (x) y = 1; // no-warning 297 return y; // expected-warning {{variable 'y' may be uninitialized when used here}} 298} 299 300void test42() { 301 int a; 302 a = 30; // no-warning 303} 304 305void test43_aux(int x); 306void test43(int i) { 307 int x; // expected-note{{initialize the variable 'x' to silence this warning}} 308 for (i = 0 ; i < 10; i++) 309 test43_aux(x++); // expected-warning {{variable 'x' is uninitialized when used here}} 310} 311 312void test44(int i) { 313 int x = i; 314 int y; // expected-note{{initialize the variable 'y' to silence this warning}} 315 for (i = 0; i < 10; i++ ) { 316 test43_aux(x++); // no-warning 317 x += y; // expected-warning {{variable 'y' is uninitialized when used here}} 318 } 319} 320 321int test45(int j) { 322 int x = 1, y = x + 1; 323 if (y) // no-warning 324 return x; 325 return y; 326} 327 328void test46() 329{ 330 int i; // expected-note{{initialize the variable 'i' to silence this warning}} 331 int j = i ? : 1; // expected-warning {{variable 'i' is uninitialized when used here}} 332} 333 334void *test47(int *i) 335{ 336 return i ? : 0; // no-warning 337} 338 339void *test49(int *i) 340{ 341 int a; 342 return &a ? : i; // no-warning 343} 344 345void test50() 346{ 347 char c[1 ? : 2]; // no-warning 348} 349 350int test51(void) 351{ 352 __block int a; 353 ^(void) { 354 a = 42; 355 }(); 356 return a; // no-warning 357} 358 359// FIXME: This is a false positive, but it tests logical operations in switch statements. 360int test52(int a, int b) { 361 int x; // expected-note {{initialize the variable 'x' to silence this warning}} 362 switch (a || b) { // expected-warning {{switch condition has boolean value}} 363 case 0: 364 x = 1; 365 break; 366 case 1: 367 x = 2; 368 break; 369 } 370 return x; // expected-warning {{variable 'x' may be uninitialized when used here}} 371} 372 373void test53() { 374 int x; // expected-note {{initialize the variable 'x' to silence this warning}} 375 int y = (x); // expected-warning {{variable 'x' is uninitialized when used here}} 376} 377 378// This CFG caused the uninitialized values warning to inf-loop. 379extern int PR10379_g(); 380void PR10379_f(int *len) { 381 int new_len; // expected-note{{initialize the variable 'new_len' to silence this warning}} 382 for (int i = 0; i < 42 && PR10379_g() == 0; i++) { 383 if (PR10379_g() == 1) 384 continue; 385 if (PR10379_g() == 2) 386 PR10379_f(&new_len); 387 else if (PR10379_g() == 3) 388 PR10379_f(&new_len); 389 *len += new_len; // expected-warning {{variable 'new_len' may be uninitialized when used here}} 390 } 391} 392 393// Test that sizeof(VLA) doesn't trigger a warning. 394void test_vla_sizeof(int x) { 395 double (*memory)[2][x] = malloc(sizeof(*memory)); // no-warning 396} 397 398// Test absurd case of deadcode + use of blocks. This previously was a false positive 399// due to an analysis bug. 400int test_block_and_dead_code() { 401 __block int x; 402 ^{ x = 1; }(); 403 if (0) 404 return x; 405 return x; // no-warning 406} 407 408// This previously triggered an infinite loop in the analysis. 409void PR11069(int a, int b) { 410 unsigned long flags; 411 for (;;) { 412 if (a && !b) 413 break; 414 } 415 for (;;) { 416 // This does not trigger a warning because it isn't a real use. 417 (void)(flags); // no-warning 418 } 419} 420 421// Test uninitialized value used in loop condition. 422void rdar9432305(float *P) { 423 int i; // expected-note {{initialize the variable 'i' to silence this warning}} 424 for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}} 425 P[i] = 0.0f; 426} 427