uninit-variables.c revision b414c4fae51c5792d3074b4b78fc8737b1d8387c
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 possibly 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 possibly 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 possibly 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 possibly 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' is possibly 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' is possibly 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' is possibly 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' is possibly uninitialized when used here}} 77} 78 79void test12(unsigned n) { 80 for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is possibly 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 94void test15() { 95 int x = x; // no-warning: signals intended lack of initialization. 96} 97 98// Don't warn in the following example; shows dataflow confluence. 99char *test16_aux(); 100void test16() { 101 char *p = test16_aux(); 102 for (unsigned i = 0 ; i < 100 ; i++) 103 p[i] = 'a'; // no-warning 104} 105 106void test17() { 107 // Don't warn multiple times about the same uninitialized variable 108 // along the same path. 109 int *x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} 110 *x = 1; // expected-warning{{variable 'x' is possibly uninitialized when used here}} 111 *x = 1; // no-warning 112} 113 114int test18(int x, int y) { 115 int z; 116 if (x && y && (z = 1)) { 117 return z; // no-warning 118 } 119 return 0; 120} 121 122int test19_aux1(); 123int test19_aux2(); 124int test19_aux3(int *x); 125int test19() { 126 int z; 127 if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z)) 128 return z; // no-warning 129 return 0; 130} 131 132int test20() { 133 int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}} 134 if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) 135 return z; // expected-warning{{variable 'z' is possibly uninitialized when used here}} 136 return 0; 137} 138 139int test21(int x, int y) { 140 int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}} 141 if ((x && y) || test19_aux3(&z) || test19_aux2()) 142 return z; // expected-warning{{variable 'z' is possibly uninitialized when used here}} 143 return 0; 144} 145 146int test22() { 147 int z; 148 while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z)) 149 return z; // no-warning 150 return 0; 151} 152 153int test23() { 154 int z; 155 for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; ) 156 return z; // no-warning 157 return 0; 158} 159 160// The basic uninitialized value analysis doesn't have enough path-sensitivity 161// to catch initializations relying on control-dependencies spanning multiple 162// conditionals. This possibly can be handled by making the CFG itself 163// represent such control-dependencies, but it is a niche case. 164int test24(int flag) { 165 unsigned val; // expected-note{{variable 'val' is declared here}} expected-note{{add initialization to silence this warning}} 166 if (flag) 167 val = 1; 168 if (!flag) 169 val = 1; 170 return val; // expected-warning{{variable 'val' is possibly uninitialized when used here}} 171} 172 173float test25() { 174 float x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} 175 return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} 176} 177 178typedef int MyInt; 179MyInt test26() { 180 MyInt x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} 181 return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} 182} 183 184// Test handling of sizeof(). 185int test27() { 186 struct test_27 { int x; } *y; 187 return sizeof(y->x); // no-warning 188} 189 190int test28() { 191 int len; // expected-note{{variable 'len' is declared here}} expected-note{{add initialization to silence this warning}} 192 return sizeof(int[len]); // expected-warning{{variable 'len' is possibly uninitialized when used here}} 193} 194 195void test29() { 196 int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} 197 (void) ^{ (void) x; }; // expected-warning{{variable 'x' is possibly uninitialized when captured by block}} 198} 199 200void test30() { 201 static int x; // no-warning 202 (void) ^{ (void) x; }; 203} 204 205void test31() { 206 __block int x; // no-warning 207 (void) ^{ (void) x; }; 208} 209 210int test32_x; 211void test32() { 212 (void) ^{ (void) test32_x; }; // no-warning 213} 214 215void test_33() { 216 int x; // no-warning 217 (void) x; 218} 219 220int test_34() { 221 int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} 222 (void) x; 223 return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} 224} 225 226// Test that this case doesn't crash. 227void test35(int x) { 228 __block int y = 0; 229 ^{ y = (x == 0); }(); 230} 231 232// Test handling of indirect goto. 233void test36() 234{ 235 void **pc; // expected-note{{variable 'pc' is declared here}} expected-note{{add initialization to silence this warning}} 236 void *dummy[] = { &&L1, &&L2 }; 237 L1: 238 goto *pc; // expected-warning{{variable 'pc' is possibly uninitialized when used here}} 239 L2: 240 goto *pc; 241} 242 243// Test && nested in ||. 244int test37_a(); 245int test37_b(); 246int test37() 247{ 248 int identifier; 249 if ((test37_a() && (identifier = 1)) || 250 (test37_b() && (identifier = 2))) { 251 return identifier; // no-warning 252 } 253 return 0; 254} 255 256// Test merging of path-specific dataflow values (without asserting). 257int test38(int r, int x, int y) 258{ 259 int z; 260 return ((r < 0) || ((r == 0) && (x < y))); 261} 262 263int test39(int x) { 264 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}} 265 int z = x + y; // expected-warning {{variable 'y' is possibly uninitialized when used here}} 266 return z; 267} 268 269 270int test40(int x) { 271 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}} 272 return x ? 1 : y; // expected-warning {{variable 'y' is possibly uninitialized when used here}} 273} 274 275int test41(int x) { 276 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}} 277 if (x) y = 1; // no-warning 278 return y; // expected-warning {{variable 'y' is possibly uninitialized when used here}} 279} 280 281void test42() { 282 int a; 283 a = 30; // no-warning 284} 285 286void test43_aux(int x); 287void test43(int i) { 288 int x; // expected-note {{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} 289 for (i = 0 ; i < 10; i++) 290 test43_aux(x++); // expected-warning {{variable 'x' is possibly uninitialized when used here}} 291} 292 293void test44(int i) { 294 int x = i; 295 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}} 296 for (i = 0; i < 10; i++ ) { 297 test43_aux(x++); // no-warning 298 x += y; // expected-warning {{variable 'y' is possibly uninitialized when used here}} 299 } 300} 301 302int test45(int j) { 303 int x = 1, y = x + 1; 304 if (y) // no-warning 305 return x; 306 return y; 307} 308 309void test46() 310{ 311 int i; // expected-note {{variable 'i' is declared here}} expected-note{{add initialization to silence this warning}} 312 int j = i ? : 1; // expected-warning {{variable 'i' is possibly uninitialized when used here}} 313} 314 315void *test47(int *i) 316{ 317 return i ? : 0; // no-warning 318} 319 320void *test49(int *i) 321{ 322 int a; 323 return &a ? : i; // no-warning 324} 325 326void test50() 327{ 328 char c[1 ? : 2]; // no-warning 329} 330 331int test51(void) 332{ 333 __block int a; 334 ^(void) { 335 a = 42; 336 }(); 337 return a; // no-warning 338} 339 340