Clang Project

clang_source_code/test/Sema/uninit-variables.c
1// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -fsyntax-only -fblocks %s -verify
2// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -ftrivial-auto-var-init=pattern -fsyntax-only -fblocks %s -verify
3
4typedef __typeof(sizeof(int)) size_t;
5void *malloc(size_t);
6
7int test1() {
8  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
9  return x; // expected-warning{{variable 'x' is uninitialized when used here}}
10}
11
12int test2() {
13  int x = 0;
14  return x; // no-warning
15}
16
17int test3() {
18  int x;
19  x = 0;
20  return x; // no-warning
21}
22
23int test4() {
24  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
25  ++x; // expected-warning{{variable 'x' is uninitialized when used here}}
26  return x; 
27}
28
29int test5() {
30  int x, y; // expected-note{{initialize the variable 'y' to silence this warning}}
31  x = y; // expected-warning{{variable 'y' is uninitialized when used here}}
32  return x;
33}
34
35int test6() {
36  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
37  x += 2; // expected-warning{{variable 'x' is uninitialized when used here}}
38  return x;
39}
40
41int test7(int y) {
42  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
43  if (y) // expected-warning{{variable 'x' is used uninitialized whenever 'if' condition is false}} \
44         // expected-note{{remove the 'if' if its condition is always true}}
45    x = 1;
46  return x; // expected-note{{uninitialized use occurs here}}
47}
48
49int test7b(int y) {
50  int x = x; // expected-note{{variable 'x' is declared here}}
51  if (y)
52    x = 1;
53  // Warn with "may be uninitialized" here (not "is sometimes uninitialized"),
54  // since the self-initialization is intended to suppress a -Wuninitialized
55  // warning.
56  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
57}
58
59int test8(int y) {
60  int x;
61  if (y)
62    x = 1;
63  else
64    x = 0;
65  return x;
66}
67
68int test9(int n) {
69  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
70  for (unsigned i = 0 ; i < n; ++i) {
71    if (i == n - 1)
72      break;
73    x = 1;
74  }
75  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
76}
77
78int test10(unsigned n) {
79  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
80  for (unsigned i = 0 ; i < n; ++i) {
81    x = 1;
82  }
83  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
84}
85
86int test11(unsigned n) {
87  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
88  for (unsigned i = 0 ; i <= n; ++i) {
89    x = 1;
90  }
91  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
92}
93
94void test12(unsigned n) {
95  for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is uninitialized when used here}} expected-note{{initialize the variable 'i' to silence this warning}}
96}
97
98int test13() {
99  static int i;
100  return i; // no-warning
101}
102
103// Simply don't crash on this test case.
104void test14() {
105  const char *p = 0;
106  for (;;) {}
107}
108
109void test15() {
110  int x = x; // no-warning: signals intended lack of initialization.
111}
112
113int test15b() {
114  // Warn here with the self-init, since it does result in a use of
115  // an uninitialized variable and this is the root cause.
116  int x = x; // expected-warning {{variable 'x' is uninitialized when used within its own initialization}}
117  return x;
118}
119
120// Don't warn in the following example; shows dataflow confluence.
121char *test16_aux();
122void test16() {
123  char *p = test16_aux();
124  for (unsigned i = 0 ; i < 100 ; i++)
125    p[i] = 'a'; // no-warning
126}
127
128void test17() {
129  // Don't warn multiple times about the same uninitialized variable
130  // along the same path.
131  int *x; // expected-note{{initialize the variable 'x' to silence this warning}}
132  *x = 1; // expected-warning{{variable 'x' is uninitialized when used here}}
133  *x = 1; // no-warning
134}
135
136int test18(int x, int y) {
137  int z;
138  if (x && y && (z = 1)) {
139    return z; // no-warning
140  }
141  return 0;
142}
143
144int test19_aux1();
145int test19_aux2();
146int test19_aux3(int *x);
147int test19() {
148  int z;
149  if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))
150    return z; // no-warning
151  return 0;
152}
153
154int test20() {
155  int z; // expected-note{{initialize the variable 'z' to silence this warning}}
156  if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}}
157    return z; // expected-note {{uninitialized use occurs here}}
158  return 0;
159}
160
161int test21(int x, int y) {
162  int z; // expected-note{{initialize the variable 'z' to silence this warning}}
163  if ((x && y) || test19_aux3(&z) || test19_aux2()) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}}
164    return z; // expected-note {{uninitialized use occurs here}}
165  return 0;
166}
167
168int test22() {
169  int z;
170  while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))
171    return z; // no-warning
172  return 0;
173}
174
175int test23() {
176  int z;
177  for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; )
178    return z; // no-warning
179  return 0;
180}
181
182// The basic uninitialized value analysis doesn't have enough path-sensitivity
183// to catch initializations relying on control-dependencies spanning multiple
184// conditionals.  This possibly can be handled by making the CFG itself
185// represent such control-dependencies, but it is a niche case.
186int test24(int flag) {
187  unsigned val; // expected-note{{initialize the variable 'val' to silence this warning}}
188  if (flag)
189    val = 1;
190  if (!flag)
191    val = 1;
192  return val; // expected-warning{{variable 'val' may be uninitialized when used here}}
193}
194
195float test25() {
196  float x; // expected-note{{initialize the variable 'x' to silence this warning}}
197  return x; // expected-warning{{variable 'x' is uninitialized when used here}}
198}
199
200typedef int MyInt;
201MyInt test26() {
202  MyInt x; // expected-note{{initialize the variable 'x' to silence this warning}}
203  return x; // expected-warning{{variable 'x' is uninitialized when used here}}
204}
205
206// Test handling of sizeof().
207int test27() {
208  struct test_27 { int x; } *y;
209  return sizeof(y->x); // no-warning
210}
211
212int test28() {
213  int len; // expected-note{{initialize the variable 'len' to silence this warning}}
214  return sizeof(int[len]); // expected-warning{{variable 'len' is uninitialized when used here}}
215}
216
217void test29() {
218  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
219  (void) ^{ (void) x; }; // expected-warning{{variable 'x' is uninitialized when captured by block}}
220}
221
222void test30() {
223  static int x; // no-warning
224  (void) ^{ (void) x; };
225}
226
227void test31() {
228  __block int x; // no-warning
229  (void) ^{ (void) x; };
230}
231
232int test32_x;
233void test32() {
234  (void) ^{ (void) test32_x; }; // no-warning
235}
236
237void test_33() {
238  int x; // no-warning
239  (void) x;
240}
241
242int test_34() {
243  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
244  (void) x;
245  return x; // expected-warning{{variable 'x' is uninitialized when used here}}
246}
247
248// Test that this case doesn't crash.
249void test35(int x) {
250  __block int y = 0;
251  ^{ y = (x == 0); }();
252}
253
254// Test handling of indirect goto.
255void test36()
256{
257  void **pc; // expected-note{{initialize the variable 'pc' to silence this warning}}
258  void *dummy[] = { &&L1, &&L2 };
259 L1:
260    goto *pc; // expected-warning{{variable 'pc' is uninitialized when used here}}
261 L2:
262    goto *pc;
263}
264
265// Test && nested in ||.
266int test37_a();
267int test37_b();
268int test37()
269{
270    int identifier;
271    if ((test37_a() && (identifier = 1)) ||
272        (test37_b() && (identifier = 2))) {
273        return identifier; // no-warning
274    }
275    return 0;
276}
277
278// Test merging of path-specific dataflow values (without asserting).
279int test38(int r, int x, int y)
280{
281  int z;
282  return ((r < 0) || ((r == 0) && (x < y)));
283}
284
285int test39(int x) {
286  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
287  int z = x + y; // expected-warning {{variable 'y' is uninitialized when used here}}
288  return z;
289}
290
291
292int test40(int x) {
293  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
294  return x ? 1 : y; // expected-warning {{variable 'y' is uninitialized when used here}}
295}
296
297int test41(int x) {
298  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
299  if (x) y = 1; // expected-warning{{variable 'y' is used uninitialized whenever 'if' condition is false}} \
300                // expected-note{{remove the 'if' if its condition is always true}}
301  return y; // expected-note{{uninitialized use occurs here}}
302}
303
304void test42() {
305  int a;
306  a = 30; // no-warning
307}
308
309void test43_aux(int x);
310void test43(int i) {
311  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
312  for (i = 0 ; i < 10; i++)
313    test43_aux(x++); // expected-warning {{variable 'x' is uninitialized when used here}}
314}
315
316void test44(int i) {
317  int x = i;
318  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
319  for (i = 0; i < 10; i++ ) {
320    test43_aux(x++); // no-warning
321    x += y; // expected-warning {{variable 'y' is uninitialized when used here}}
322  }
323}
324
325int test45(int j) {
326  int x = 1, y = x + 1;
327  if (y) // no-warning
328    return x;
329  return y;
330}
331
332void test46()
333{
334  int i; // expected-note{{initialize the variable 'i' to silence this warning}}
335  int j = i ? : 1; // expected-warning {{variable 'i' is uninitialized when used here}}
336}
337
338void *test47(int *i)
339{
340  return i ? : 0; // no-warning
341}
342
343void *test49(int *i)
344{
345  int a;
346  return &a ? : i; // no-warning
347}
348
349void test50()
350{
351  char c[1 ? : 2]; // no-warning
352}
353
354int test51(void)
355{
356    __block int a;
357    ^(void) {
358      a = 42;
359    }();
360    return a; // no-warning
361}
362
363// FIXME: This is a false positive, but it tests logical operations in switch statements.
364int test52(int a, int b) {
365  int x;  // expected-note {{initialize the variable 'x' to silence this warning}}
366  switch (a || b) { // expected-warning {{switch condition has boolean value}}
367    case 0:
368      x = 1;
369      break;
370    case 1:
371      x = 2;
372      break;
373  }
374  return x; // expected-warning {{variable 'x' may be uninitialized when used here}}
375}
376
377void test53() {
378  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
379  int y = (x);  // expected-warning {{variable 'x' is uninitialized when used here}}
380}
381
382// This CFG caused the uninitialized values warning to inf-loop.
383extern int PR10379_g();
384void PR10379_f(int *len) {
385  int new_len; // expected-note{{initialize the variable 'new_len' to silence this warning}}
386  for (int i = 0; i < 42 && PR10379_g() == 0; i++) {
387    if (PR10379_g() == 1)
388      continue;
389    if (PR10379_g() == 2)
390      PR10379_f(&new_len);
391    else if (PR10379_g() == 3)
392      PR10379_f(&new_len);
393    *len += new_len; // expected-warning {{variable 'new_len' may be uninitialized when used here}}
394  }
395}
396
397// Test that sizeof(VLA) doesn't trigger a warning.
398void test_vla_sizeof(int x) {
399  double (*memory)[2][x] = malloc(sizeof(*memory)); // no-warning
400}
401
402// Test absurd case of deadcode + use of blocks.  This previously was a false positive
403// due to an analysis bug.
404int test_block_and_dead_code() {
405  __block int x;
406  ^{ x = 1; }();
407  if (0)
408    return x;
409  return x; // no-warning
410}
411
412// This previously triggered an infinite loop in the analysis.
413void PR11069(int a, int b) {
414  unsigned long flags;
415  for (;;) {
416    if (a && !b)
417      break;
418  }
419  for (;;) {
420    // This does not trigger a warning because it isn't a real use.
421    (void)(flags); // no-warning
422  }
423}
424
425// Test uninitialized value used in loop condition.
426void rdar9432305(float *P) {
427  int i; // expected-note {{initialize the variable 'i' to silence this warning}}
428  for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}}
429    P[i] = 0.0f;
430}
431
432// Test that fixits are not emitted inside macros.
433#define UNINIT(T, x, y) T x; T y = x;
434#define ASSIGN(T, x, y) T y = x;
435void test54() {
436  UNINIT(int, a, b);  // expected-warning {{variable 'a' is uninitialized when used here}} \
437                      // expected-note {{variable 'a' is declared here}}
438  int c;  // expected-note {{initialize the variable 'c' to silence this warning}}
439  ASSIGN(int, c, d);  // expected-warning {{variable 'c' is uninitialized when used here}}
440}
441
442// Taking the address is fine
443struct { struct { void *p; } a; } test55 = { { &test55.a }}; // no-warning
444struct { struct { void *p; } a; } test56 = { { &(test56.a) }}; // no-warning
445
446void uninit_in_loop() {
447  int produce(void);
448  void consume(int);
449  for (int n = 0; n < 100; ++n) {
450    int k; // expected-note {{initialize}}
451    consume(k); // expected-warning {{variable 'k' is uninitialized}}
452    k = produce();
453  }
454}
455
456void uninit_in_loop_goto() {
457  int produce(void);
458  void consume(int);
459  for (int n = 0; n < 100; ++n) {
460    goto skip_decl;
461    int k; // expected-note {{initialize}}
462skip_decl:
463    // FIXME: This should produce the 'is uninitialized' diagnostic, but we
464    // don't have enough information in the CFG to easily tell that the
465    // variable's scope has been left and re-entered.
466    consume(k); // expected-warning {{variable 'k' may be uninitialized}}
467    k = produce();
468  }
469}
470
471typedef char jmp_buf[256];
472extern int setjmp(jmp_buf env); // implicitly returns_twice
473
474void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn));
475
476int returns_twice() {
477  int a; // expected-note {{initialize}}
478  if (!a) { // expected-warning {{variable 'a' is uninitialized}}
479    jmp_buf env;
480    int b;
481    if (setjmp(env) == 0) {
482      do_stuff_and_longjmp(env, &b);
483    } else {
484      a = b; // no warning
485    }
486  }
487  return a;
488}
489
490int compound_assign(int *arr, int n) {
491  int sum; // expected-note {{initialize}}
492  for (int i = 0; i < n; ++i)
493    sum += arr[i]; // expected-warning {{variable 'sum' is uninitialized}}
494  return sum / n;
495}
496
497int compound_assign_2() {
498  int x; // expected-note {{initialize}}
499  return x += 1; // expected-warning {{variable 'x' is uninitialized}}
500}
501
502int compound_assign_3() {
503  int x; // expected-note {{initialize}}
504  x *= 0; // expected-warning {{variable 'x' is uninitialized}}
505  return x;
506}
507
508int self_init_in_cond(int *p) {
509  int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok
510  return n;
511}
512
513void test_analyzer_noreturn_aux() __attribute__((analyzer_noreturn));
514
515void test_analyzer_noreturn(int y) {
516  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
517  if (y) {
518    test_analyzer_noreturn_aux();
519 ++x; // no-warning
520  }
521  else {
522 ++x; // expected-warning {{variable 'x' is uninitialized when used here}}
523  }
524}
525void test_analyzer_noreturn_2(int y) {
526  int x;
527  if (y) {
528    test_analyzer_noreturn_aux();
529  }
530  else {
531 x = 1;
532  }
533  ++x; // no-warning
534}
535