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