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