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