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