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