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