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