1 // RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -fsyntax-only -fblocks %s -verify
2
test1()3 int 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 uninitialized when used here}}
6 }
7
test2()8 int test2() {
9 int x = 0;
10 return x; // no-warning
11 }
12
test3()13 int test3() {
14 int x;
15 x = 0;
16 return x; // no-warning
17 }
18
test4()19 int 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 uninitialized when used here}}
22 return x;
23 }
24
test5()25 int 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 uninitialized when used here}}
28 return x;
29 }
30
test6()31 int 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 uninitialized when used here}}
34 return x;
35 }
36
test7(int y)37 int 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' may be uninitialized when used here}}
42 }
43
test8(int y)44 int test8(int y) {
45 int x;
46 if (y)
47 x = 1;
48 else
49 x = 0;
50 return x;
51 }
52
test9(int n)53 int 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' may be uninitialized when used here}}
61 }
62
test10(unsigned n)63 int 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' may be uninitialized when used here}}
69 }
70
test11(unsigned n)71 int 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' may be uninitialized when used here}}
77 }
78
test12(unsigned n)79 void test12(unsigned n) {
80 for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' may be uninitialized when used here}} expected-note{{variable 'i' is declared here}} expected-note{{add initialization to silence this warning}}
81 }
82
test13()83 int test13() {
84 static int i;
85 return i; // no-warning
86 }
87
88 // Simply don't crash on this test case.
test14()89 void test14() {
90 const char *p = 0;
91 for (;;) {}
92 }
93
test15()94 int test15() {
95 int x = x; // no-warning: signals intended lack of initialization. \
96 // expected-note{{variable 'x' is declared here}}
97 return x; // expected-warning{{variable 'x' is uninitialized when used here}}
98 }
99
100 // Don't warn in the following example; shows dataflow confluence.
101 char *test16_aux();
test16()102 void test16() {
103 char *p = test16_aux();
104 for (unsigned i = 0 ; i < 100 ; i++)
105 p[i] = 'a'; // no-warning
106 }
107
test17()108 void test17() {
109 // Don't warn multiple times about the same uninitialized variable
110 // along the same path.
111 int *x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
112 *x = 1; // expected-warning{{variable 'x' is uninitialized when used here}}
113 *x = 1; // no-warning
114 }
115
test18(int x,int y)116 int test18(int x, int y) {
117 int z;
118 if (x && y && (z = 1)) {
119 return z; // no-warning
120 }
121 return 0;
122 }
123
124 int test19_aux1();
125 int test19_aux2();
126 int test19_aux3(int *x);
test19()127 int test19() {
128 int z;
129 if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))
130 return z; // no-warning
131 return 0;
132 }
133
test20()134 int test20() {
135 int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}}
136 if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z))
137 return z; // expected-warning{{variable 'z' may be uninitialized when used here}}
138 return 0;
139 }
140
test21(int x,int y)141 int test21(int x, int y) {
142 int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}}
143 if ((x && y) || test19_aux3(&z) || test19_aux2())
144 return z; // expected-warning{{variable 'z' may be uninitialized when used here}}
145 return 0;
146 }
147
test22()148 int test22() {
149 int z;
150 while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))
151 return z; // no-warning
152 return 0;
153 }
154
test23()155 int test23() {
156 int z;
157 for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; )
158 return z; // no-warning
159 return 0;
160 }
161
162 // The basic uninitialized value analysis doesn't have enough path-sensitivity
163 // to catch initializations relying on control-dependencies spanning multiple
164 // conditionals. This possibly can be handled by making the CFG itself
165 // represent such control-dependencies, but it is a niche case.
test24(int flag)166 int test24(int flag) {
167 unsigned val; // expected-note{{variable 'val' is declared here}} expected-note{{add initialization to silence this warning}}
168 if (flag)
169 val = 1;
170 if (!flag)
171 val = 1;
172 return val; // expected-warning{{variable 'val' may be uninitialized when used here}}
173 }
174
test25()175 float test25() {
176 float x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
177 return x; // expected-warning{{variable 'x' is uninitialized when used here}}
178 }
179
180 typedef int MyInt;
test26()181 MyInt test26() {
182 MyInt x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
183 return x; // expected-warning{{variable 'x' is uninitialized when used here}}
184 }
185
186 // Test handling of sizeof().
test27()187 int test27() {
188 struct test_27 { int x; } *y;
189 return sizeof(y->x); // no-warning
190 }
191
test28()192 int test28() {
193 int len; // expected-note{{variable 'len' is declared here}} expected-note{{add initialization to silence this warning}}
194 return sizeof(int[len]); // expected-warning{{variable 'len' is uninitialized when used here}}
195 }
196
test29()197 void test29() {
198 int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
199 (void) ^{ (void) x; }; // expected-warning{{variable 'x' is uninitialized when captured by block}}
200 }
201
test30()202 void test30() {
203 static int x; // no-warning
204 (void) ^{ (void) x; };
205 }
206
test31()207 void test31() {
208 __block int x; // no-warning
209 (void) ^{ (void) x; };
210 }
211
212 int test32_x;
test32()213 void test32() {
214 (void) ^{ (void) test32_x; }; // no-warning
215 }
216
test_33()217 void test_33() {
218 int x; // no-warning
219 (void) x;
220 }
221
test_34()222 int test_34() {
223 int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
224 (void) x;
225 return x; // expected-warning{{variable 'x' is uninitialized when used here}}
226 }
227
228 // Test that this case doesn't crash.
test35(int x)229 void test35(int x) {
230 __block int y = 0;
231 ^{ y = (x == 0); }();
232 }
233
234 // Test handling of indirect goto.
test36()235 void test36()
236 {
237 void **pc; // expected-note{{variable 'pc' is declared here}} expected-note{{add initialization to silence this warning}}
238 void *dummy[] = { &&L1, &&L2 };
239 L1:
240 goto *pc; // expected-warning{{variable 'pc' may be uninitialized when used here}}
241 L2:
242 goto *pc;
243 }
244
245 // Test && nested in ||.
246 int test37_a();
247 int test37_b();
test37()248 int test37()
249 {
250 int identifier;
251 if ((test37_a() && (identifier = 1)) ||
252 (test37_b() && (identifier = 2))) {
253 return identifier; // no-warning
254 }
255 return 0;
256 }
257
258 // Test merging of path-specific dataflow values (without asserting).
test38(int r,int x,int y)259 int test38(int r, int x, int y)
260 {
261 int z;
262 return ((r < 0) || ((r == 0) && (x < y)));
263 }
264
test39(int x)265 int test39(int x) {
266 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
267 int z = x + y; // expected-warning {{variable 'y' is uninitialized when used here}}
268 return z;
269 }
270
271
test40(int x)272 int test40(int x) {
273 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
274 return x ? 1 : y; // expected-warning {{variable 'y' is uninitialized when used here}}
275 }
276
test41(int x)277 int test41(int x) {
278 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
279 if (x) y = 1; // no-warning
280 return y; // expected-warning {{variable 'y' may be uninitialized when used here}}
281 }
282
test42()283 void test42() {
284 int a;
285 a = 30; // no-warning
286 }
287
288 void test43_aux(int x);
test43(int i)289 void test43(int i) {
290 int x; // expected-note {{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
291 for (i = 0 ; i < 10; i++)
292 test43_aux(x++); // expected-warning {{variable 'x' may be uninitialized when used here}}
293 }
294
test44(int i)295 void test44(int i) {
296 int x = i;
297 int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
298 for (i = 0; i < 10; i++ ) {
299 test43_aux(x++); // no-warning
300 x += y; // expected-warning {{variable 'y' may be uninitialized when used here}}
301 }
302 }
303
test45(int j)304 int test45(int j) {
305 int x = 1, y = x + 1;
306 if (y) // no-warning
307 return x;
308 return y;
309 }
310
test46()311 void test46()
312 {
313 int i; // expected-note {{variable 'i' is declared here}} expected-note{{add initialization to silence this warning}}
314 int j = i ? : 1; // expected-warning {{variable 'i' is uninitialized when used here}}
315 }
316
test47(int * i)317 void *test47(int *i)
318 {
319 return i ? : 0; // no-warning
320 }
321
test49(int * i)322 void *test49(int *i)
323 {
324 int a;
325 return &a ? : i; // no-warning
326 }
327
test50()328 void test50()
329 {
330 char c[1 ? : 2]; // no-warning
331 }
332
test51(void)333 int test51(void)
334 {
335 __block int a;
336 ^(void) {
337 a = 42;
338 }();
339 return a; // no-warning
340 }
341
342 // FIXME: This is a false positive, but it tests logical operations in switch statements.
test52(int a,int b)343 int test52(int a, int b) {
344 int x; // expected-note {{variable 'x' is declared here}} expected-note {{add initialization to silence this warning}}
345 switch (a || b) { // expected-warning {{switch condition has boolean value}}
346 case 0:
347 x = 1;
348 break;
349 case 1:
350 x = 2;
351 break;
352 }
353 return x; // expected-warning {{variable 'x' may be uninitialized when used here}}
354 }
355
test53()356 void test53() {
357 int x; // expected-note {{variable 'x' is declared here}} expected-note {{add initialization to silence this warning}}
358 int y = (x); // expected-warning {{variable 'x' is uninitialized when used here}}
359 }
360
361 // This CFG caused the uninitialized values warning to inf-loop.
362 extern int PR10379_g();
PR10379_f(int * len)363 void PR10379_f(int *len) {
364 int new_len; // expected-note {{variable 'new_len' is declared here}} expected-note{{add initialization to silence this warning}}
365 for (int i = 0; i < 42 && PR10379_g() == 0; i++) {
366 if (PR10379_g() == 1)
367 continue;
368 if (PR10379_g() == 2)
369 PR10379_f(&new_len);
370 else if (PR10379_g() == 3)
371 PR10379_f(&new_len);
372 *len += new_len; // expected-warning {{variable 'new_len' may be uninitialized when used here}}
373 }
374 }
375