xref: /aosp_15_r20/external/clang/test/Analysis/dead-stores.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
2*67e74705SXin Li // RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores -analyzer-store=region -analyzer-constraints=range -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
3*67e74705SXin Li 
f1()4*67e74705SXin Li void f1() {
5*67e74705SXin Li   int k, y; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}}
6*67e74705SXin Li   int abc=1;
7*67e74705SXin Li   long idx=abc+3*5; // expected-warning {{never read}} expected-warning{{unused variable 'idx'}}
8*67e74705SXin Li }
9*67e74705SXin Li 
f2(void * b)10*67e74705SXin Li void f2(void *b) {
11*67e74705SXin Li  char *c = (char*)b; // no-warning
12*67e74705SXin Li  char *d = b+1; // expected-warning {{never read}} expected-warning{{unused variable 'd'}}
13*67e74705SXin Li  printf("%s", c); // expected-warning{{implicitly declaring library function 'printf' with type 'int (const char *, ...)'}} \
14*67e74705SXin Li  // expected-note{{include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
15*67e74705SXin Li }
16*67e74705SXin Li 
17*67e74705SXin Li int f();
18*67e74705SXin Li 
f3()19*67e74705SXin Li void f3() {
20*67e74705SXin Li   int r;
21*67e74705SXin Li   if ((r = f()) != 0) { // no-warning
22*67e74705SXin Li     int y = r; // no-warning
23*67e74705SXin Li     printf("the error is: %d\n", y);
24*67e74705SXin Li   }
25*67e74705SXin Li }
26*67e74705SXin Li 
f4(int k)27*67e74705SXin Li void f4(int k) {
28*67e74705SXin Li 
29*67e74705SXin Li   k = 1;
30*67e74705SXin Li 
31*67e74705SXin Li   if (k)
32*67e74705SXin Li     f1();
33*67e74705SXin Li 
34*67e74705SXin Li   k = 2;  // expected-warning {{never read}}
35*67e74705SXin Li }
36*67e74705SXin Li 
f5()37*67e74705SXin Li void f5() {
38*67e74705SXin Li 
39*67e74705SXin Li   int x = 4; // no-warning
40*67e74705SXin Li   int *p = &x; // expected-warning{{never read}} expected-warning{{unused variable 'p'}}
41*67e74705SXin Li 
42*67e74705SXin Li }
43*67e74705SXin Li 
44*67e74705SXin Li //
f6()45*67e74705SXin Li int f6() {
46*67e74705SXin Li 
47*67e74705SXin Li   int x = 4;
48*67e74705SXin Li   ++x; // no-warning
49*67e74705SXin Li   return 1;
50*67e74705SXin Li }
51*67e74705SXin Li 
f7(int * p)52*67e74705SXin Li int f7(int *p) {
53*67e74705SXin Li   // This is allowed for defensive programming.
54*67e74705SXin Li   p = 0; // no-warning
55*67e74705SXin Li   return 1;
56*67e74705SXin Li }
57*67e74705SXin Li 
f7b(int * p)58*67e74705SXin Li int f7b(int *p) {
59*67e74705SXin Li   // This is allowed for defensive programming.
60*67e74705SXin Li   p = (0); // no-warning
61*67e74705SXin Li   return 1;
62*67e74705SXin Li }
63*67e74705SXin Li 
f7c(int * p)64*67e74705SXin Li int f7c(int *p) {
65*67e74705SXin Li   // This is allowed for defensive programming.
66*67e74705SXin Li   p = (void*) 0; // no-warning
67*67e74705SXin Li   return 1;
68*67e74705SXin Li }
69*67e74705SXin Li 
f7d(int * p)70*67e74705SXin Li int f7d(int *p) {
71*67e74705SXin Li   // This is allowed for defensive programming.
72*67e74705SXin Li   p = (void*) (0); // no-warning
73*67e74705SXin Li   return 1;
74*67e74705SXin Li }
75*67e74705SXin Li 
76*67e74705SXin Li // Don't warn for dead stores in nested expressions.  We have yet
77*67e74705SXin Li // to see a real bug in this scenario.
f8(int * p)78*67e74705SXin Li int f8(int *p) {
79*67e74705SXin Li   extern int *baz();
80*67e74705SXin Li   if ((p = baz())) // no-warning
81*67e74705SXin Li     return 1;
82*67e74705SXin Li   return 0;
83*67e74705SXin Li }
84*67e74705SXin Li 
f9()85*67e74705SXin Li int f9() {
86*67e74705SXin Li   int x = 4;
87*67e74705SXin Li   x = x + 10; // expected-warning{{never read}}
88*67e74705SXin Li   return 1;
89*67e74705SXin Li }
90*67e74705SXin Li 
f10()91*67e74705SXin Li int f10() {
92*67e74705SXin Li   int x = 4;
93*67e74705SXin Li   x = 10 + x; // expected-warning{{never read}}
94*67e74705SXin Li   return 1;
95*67e74705SXin Li }
96*67e74705SXin Li 
f11()97*67e74705SXin Li int f11() {
98*67e74705SXin Li   int x = 4;
99*67e74705SXin Li   return x++; // expected-warning{{never read}}
100*67e74705SXin Li }
101*67e74705SXin Li 
f11b()102*67e74705SXin Li int f11b() {
103*67e74705SXin Li   int x = 4;
104*67e74705SXin Li   return ((((++x)))); // no-warning
105*67e74705SXin Li }
106*67e74705SXin Li 
f12a(int y)107*67e74705SXin Li int f12a(int y) {
108*67e74705SXin Li   int x = y;  // expected-warning{{unused variable 'x'}}
109*67e74705SXin Li   return 1;
110*67e74705SXin Li }
f12b(int y)111*67e74705SXin Li int f12b(int y) {
112*67e74705SXin Li   int x __attribute__((unused)) = y;  // no-warning
113*67e74705SXin Li   return 1;
114*67e74705SXin Li }
f12c(int y)115*67e74705SXin Li int f12c(int y) {
116*67e74705SXin Li   // Allow initialiation of scalar variables by parameters as a form of
117*67e74705SXin Li   // defensive programming.
118*67e74705SXin Li   int x = y;  // no-warning
119*67e74705SXin Li   x = 1;
120*67e74705SXin Li   return x;
121*67e74705SXin Li }
122*67e74705SXin Li 
123*67e74705SXin Li // Filed with PR 2630.  This code should produce no warnings.
f13(void)124*67e74705SXin Li int f13(void)
125*67e74705SXin Li {
126*67e74705SXin Li   int a = 1;
127*67e74705SXin Li   int b, c = b = a + a;
128*67e74705SXin Li 
129*67e74705SXin Li   if (b > 0)
130*67e74705SXin Li     return (0);
131*67e74705SXin Li 
132*67e74705SXin Li   return (a + b + c);
133*67e74705SXin Li }
134*67e74705SXin Li 
135*67e74705SXin Li // Filed with PR 2763.
f14(int count)136*67e74705SXin Li int f14(int count) {
137*67e74705SXin Li   int index, nextLineIndex;
138*67e74705SXin Li   for (index = 0; index < count; index = nextLineIndex+1) {
139*67e74705SXin Li     nextLineIndex = index+1;  // no-warning
140*67e74705SXin Li     continue;
141*67e74705SXin Li   }
142*67e74705SXin Li   return index;
143*67e74705SXin Li }
144*67e74705SXin Li 
145*67e74705SXin Li // Test case for <rdar://problem/6248086>
f15(unsigned x,unsigned y)146*67e74705SXin Li void f15(unsigned x, unsigned y) {
147*67e74705SXin Li   int count = x * y;   // no-warning
148*67e74705SXin Li   int z[count]; // expected-warning{{unused variable 'z'}}
149*67e74705SXin Li }
150*67e74705SXin Li 
151*67e74705SXin Li // Don't warn for dead stores in nested expressions.  We have yet
152*67e74705SXin Li // to see a real bug in this scenario.
f16(int x)153*67e74705SXin Li int f16(int x) {
154*67e74705SXin Li   x = x * 2;
155*67e74705SXin Li   x = sizeof(int [x = (x || x + 1) * 2])
156*67e74705SXin Li       ? 5 : 8;
157*67e74705SXin Li   return x;
158*67e74705SXin Li }
159*67e74705SXin Li 
160*67e74705SXin Li // Self-assignments should not be flagged as dead stores.
f17()161*67e74705SXin Li void f17() {
162*67e74705SXin Li   int x = 1;
163*67e74705SXin Li   x = x;
164*67e74705SXin Li }
165*67e74705SXin Li 
166*67e74705SXin Li // <rdar://problem/6506065>
167*67e74705SXin Li // The values of dead stores are only "consumed" in an enclosing expression
168*67e74705SXin Li // what that value is actually used.  In other words, don't say "Although the
169*67e74705SXin Li // value stored to 'x' is used...".
f18()170*67e74705SXin Li int f18() {
171*67e74705SXin Li    int x = 0; // no-warning
172*67e74705SXin Li    if (1)
173*67e74705SXin Li       x = 10;  // expected-warning{{Value stored to 'x' is never read}}
174*67e74705SXin Li    while (1)
175*67e74705SXin Li       x = 10;  // expected-warning{{Value stored to 'x' is never read}}
176*67e74705SXin Li    // unreachable.
177*67e74705SXin Li    do
178*67e74705SXin Li       x = 10;   // no-warning
179*67e74705SXin Li    while (1);
180*67e74705SXin Li    return (x = 10); // no-warning
181*67e74705SXin Li }
182*67e74705SXin Li 
f18_a()183*67e74705SXin Li int f18_a() {
184*67e74705SXin Li    int x = 0; // no-warning
185*67e74705SXin Li    return (x = 10); // no-warning
186*67e74705SXin Li }
187*67e74705SXin Li 
f18_b()188*67e74705SXin Li void f18_b() {
189*67e74705SXin Li    int x = 0; // no-warning
190*67e74705SXin Li    if (1)
191*67e74705SXin Li       x = 10;  // expected-warning{{Value stored to 'x' is never read}}
192*67e74705SXin Li }
193*67e74705SXin Li 
f18_c()194*67e74705SXin Li void f18_c() {
195*67e74705SXin Li   int x = 0;
196*67e74705SXin Li   while (1)
197*67e74705SXin Li      x = 10;  // expected-warning{{Value stored to 'x' is never read}}
198*67e74705SXin Li }
199*67e74705SXin Li 
f18_d()200*67e74705SXin Li void f18_d() {
201*67e74705SXin Li   int x = 0; // no-warning
202*67e74705SXin Li   do
203*67e74705SXin Li      x = 10;   // expected-warning{{Value stored to 'x' is never read}}
204*67e74705SXin Li   while (1);
205*67e74705SXin Li }
206*67e74705SXin Li 
207*67e74705SXin Li // PR 3514: false positive `dead initialization` warning for init to global
208*67e74705SXin Li //  http://llvm.org/bugs/show_bug.cgi?id=3514
209*67e74705SXin Li extern const int MyConstant;
f19(void)210*67e74705SXin Li int f19(void) {
211*67e74705SXin Li   int x = MyConstant;  // no-warning
212*67e74705SXin Li   x = 1;
213*67e74705SXin Li   return x;
214*67e74705SXin Li }
215*67e74705SXin Li 
f19b(void)216*67e74705SXin Li int f19b(void) { // This case is the same as f19.
217*67e74705SXin Li   const int MyConstant = 0;
218*67e74705SXin Li   int x = MyConstant; // no-warning
219*67e74705SXin Li   x = 1;
220*67e74705SXin Li   return x;
221*67e74705SXin Li }
222*67e74705SXin Li 
f20(void)223*67e74705SXin Li void f20(void) {
224*67e74705SXin Li   int x = 1; // no-warning
225*67e74705SXin Li #pragma unused(x)
226*67e74705SXin Li }
227*67e74705SXin Li 
228*67e74705SXin Li void halt() __attribute__((noreturn));
f21()229*67e74705SXin Li int f21() {
230*67e74705SXin Li   int x = 4;
231*67e74705SXin Li 
232*67e74705SXin Li   x = x + 1; // expected-warning{{never read}}
233*67e74705SXin Li   if (1) {
234*67e74705SXin Li     halt();
235*67e74705SXin Li     (void)x;
236*67e74705SXin Li   }
237*67e74705SXin Li   return 1;
238*67e74705SXin Li }
239*67e74705SXin Li 
240*67e74705SXin Li int j;
f22()241*67e74705SXin Li void f22() {
242*67e74705SXin Li   int x = 4;
243*67e74705SXin Li   int y1 = 4;
244*67e74705SXin Li   int y2 = 4;
245*67e74705SXin Li   int y3 = 4;
246*67e74705SXin Li   int y4 = 4;
247*67e74705SXin Li   int y5 = 4;
248*67e74705SXin Li   int y6 = 4;
249*67e74705SXin Li   int y7 = 4;
250*67e74705SXin Li   int y8 = 4;
251*67e74705SXin Li   int y9 = 4;
252*67e74705SXin Li   int y10 = 4;
253*67e74705SXin Li   int y11 = 4;
254*67e74705SXin Li   int y12 = 4;
255*67e74705SXin Li   int y13 = 4;
256*67e74705SXin Li   int y14 = 4;
257*67e74705SXin Li   int y15 = 4;
258*67e74705SXin Li   int y16 = 4;
259*67e74705SXin Li   int y17 = 4;
260*67e74705SXin Li   int y18 = 4;
261*67e74705SXin Li   int y19 = 4;
262*67e74705SXin Li   int y20 = 4;
263*67e74705SXin Li 
264*67e74705SXin Li   x = x + 1; // expected-warning{{never read}}
265*67e74705SXin Li   ++y1;
266*67e74705SXin Li   ++y2;
267*67e74705SXin Li   ++y3;
268*67e74705SXin Li   ++y4;
269*67e74705SXin Li   ++y5;
270*67e74705SXin Li   ++y6;
271*67e74705SXin Li   ++y7;
272*67e74705SXin Li   ++y8;
273*67e74705SXin Li   ++y9;
274*67e74705SXin Li   ++y10;
275*67e74705SXin Li   ++y11;
276*67e74705SXin Li   ++y12;
277*67e74705SXin Li   ++y13;
278*67e74705SXin Li   ++y14;
279*67e74705SXin Li   ++y15;
280*67e74705SXin Li   ++y16;
281*67e74705SXin Li   ++y17;
282*67e74705SXin Li   ++y18;
283*67e74705SXin Li   ++y19;
284*67e74705SXin Li   ++y20;
285*67e74705SXin Li 
286*67e74705SXin Li   switch (j) {
287*67e74705SXin Li   case 1:
288*67e74705SXin Li     if (0)
289*67e74705SXin Li       (void)x;
290*67e74705SXin Li     if (1) {
291*67e74705SXin Li       (void)y1;
292*67e74705SXin Li       return;
293*67e74705SXin Li     }
294*67e74705SXin Li     (void)x;
295*67e74705SXin Li     break;
296*67e74705SXin Li   case 2:
297*67e74705SXin Li     if (0)
298*67e74705SXin Li       (void)x;
299*67e74705SXin Li     else {
300*67e74705SXin Li       (void)y2;
301*67e74705SXin Li       return;
302*67e74705SXin Li     }
303*67e74705SXin Li     (void)x;
304*67e74705SXin Li     break;
305*67e74705SXin Li   case 3:
306*67e74705SXin Li     if (1) {
307*67e74705SXin Li       (void)y3;
308*67e74705SXin Li       return;
309*67e74705SXin Li     } else
310*67e74705SXin Li       (void)x;
311*67e74705SXin Li     (void)x;
312*67e74705SXin Li   break;
313*67e74705SXin Li   case 4:
314*67e74705SXin Li     0 ? : ((void)y4, ({ return; }));
315*67e74705SXin Li     (void)x;
316*67e74705SXin Li     break;
317*67e74705SXin Li   case 5:
318*67e74705SXin Li     1 ? : (void)x;
319*67e74705SXin Li     0 ? (void)x : ((void)y5, ({ return; }));
320*67e74705SXin Li     (void)x;
321*67e74705SXin Li     break;
322*67e74705SXin Li   case 6:
323*67e74705SXin Li     1 ? ((void)y6, ({ return; })) : (void)x;
324*67e74705SXin Li     (void)x;
325*67e74705SXin Li     break;
326*67e74705SXin Li   case 7:
327*67e74705SXin Li     (void)(0 && x);
328*67e74705SXin Li     (void)y7;
329*67e74705SXin Li     (void)(0 || (y8, ({ return; }), 1));  // expected-warning {{expression result unused}}
330*67e74705SXin Li     (void)x;
331*67e74705SXin Li     break;
332*67e74705SXin Li   case 8:
333*67e74705SXin Li     (void)(1 && (y9, ({ return; }), 1));  // expected-warning {{expression result unused}}
334*67e74705SXin Li     (void)x;
335*67e74705SXin Li     break;
336*67e74705SXin Li   case 9:
337*67e74705SXin Li     (void)(1 || x);
338*67e74705SXin Li     (void)y10;
339*67e74705SXin Li     break;
340*67e74705SXin Li   case 10:
341*67e74705SXin Li     while (0) {
342*67e74705SXin Li       (void)x;
343*67e74705SXin Li     }
344*67e74705SXin Li     (void)y11;
345*67e74705SXin Li     break;
346*67e74705SXin Li   case 11:
347*67e74705SXin Li     while (1) {
348*67e74705SXin Li       (void)y12;
349*67e74705SXin Li     }
350*67e74705SXin Li     (void)x;
351*67e74705SXin Li     break;
352*67e74705SXin Li   case 12:
353*67e74705SXin Li     do {
354*67e74705SXin Li       (void)y13;
355*67e74705SXin Li     } while (0);
356*67e74705SXin Li     (void)y14;
357*67e74705SXin Li     break;
358*67e74705SXin Li   case 13:
359*67e74705SXin Li     do {
360*67e74705SXin Li       (void)y15;
361*67e74705SXin Li     } while (1);
362*67e74705SXin Li     (void)x;
363*67e74705SXin Li     break;
364*67e74705SXin Li   case 14:
365*67e74705SXin Li     for (;;) {
366*67e74705SXin Li       (void)y16;
367*67e74705SXin Li     }
368*67e74705SXin Li     (void)x;
369*67e74705SXin Li     break;
370*67e74705SXin Li   case 15:
371*67e74705SXin Li     for (;1;) {
372*67e74705SXin Li       (void)y17;
373*67e74705SXin Li     }
374*67e74705SXin Li     (void)x;
375*67e74705SXin Li     break;
376*67e74705SXin Li   case 16:
377*67e74705SXin Li     for (;0;) {
378*67e74705SXin Li       (void)x;
379*67e74705SXin Li     }
380*67e74705SXin Li     (void)y18;
381*67e74705SXin Li     break;
382*67e74705SXin Li   case 17:
383*67e74705SXin Li     __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));
384*67e74705SXin Li     (void)x;
385*67e74705SXin Li     break;
386*67e74705SXin Li   case 19:
387*67e74705SXin Li     __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);
388*67e74705SXin Li     (void)x;
389*67e74705SXin Li     break;
390*67e74705SXin Li   }
391*67e74705SXin Li }
392*67e74705SXin Li 
393*67e74705SXin Li void f23_aux(const char* s);
f23(int argc,char ** argv)394*67e74705SXin Li void f23(int argc, char **argv) {
395*67e74705SXin Li   int shouldLog = (argc > 1); // no-warning
396*67e74705SXin Li   ^{
397*67e74705SXin Li      if (shouldLog) f23_aux("I did too use it!\n");
398*67e74705SXin Li      else f23_aux("I shouldn't log.  Wait.. d'oh!\n");
399*67e74705SXin Li   }();
400*67e74705SXin Li }
401*67e74705SXin Li 
f23_pos(int argc,char ** argv)402*67e74705SXin Li void f23_pos(int argc, char **argv) {
403*67e74705SXin Li   int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} expected-warning{{unused variable 'shouldLog'}}
404*67e74705SXin Li   ^{
405*67e74705SXin Li      f23_aux("I did too use it!\n");
406*67e74705SXin Li   }();
407*67e74705SXin Li }
408*67e74705SXin Li 
f24_A(int y)409*67e74705SXin Li void f24_A(int y) {
410*67e74705SXin Li   // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
411*67e74705SXin Li   int x = (y > 2); // no-warning
412*67e74705SXin Li   ^ {
413*67e74705SXin Li       int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}} expected-warning{{unused variable 'z'}}
414*67e74705SXin Li   }();
415*67e74705SXin Li }
416*67e74705SXin Li 
f24_B(int y)417*67e74705SXin Li void f24_B(int y) {
418*67e74705SXin Li   // FIXME: One day this should be reported as dead since 'x' is just overwritten.
419*67e74705SXin Li   __block int x = (y > 2); // no-warning
420*67e74705SXin Li   ^{
421*67e74705SXin Li     // FIXME: This should eventually be a dead store since it is never read either.
422*67e74705SXin Li     x = 5; // no-warning
423*67e74705SXin Li   }();
424*67e74705SXin Li }
425*67e74705SXin Li 
f24_C(int y)426*67e74705SXin Li int f24_C(int y) {
427*67e74705SXin Li   // FIXME: One day this should be reported as dead since 'x' is just overwritten.
428*67e74705SXin Li   __block int x = (y > 2); // no-warning
429*67e74705SXin Li   ^{
430*67e74705SXin Li     x = 5; // no-warning
431*67e74705SXin Li   }();
432*67e74705SXin Li   return x;
433*67e74705SXin Li }
434*67e74705SXin Li 
f24_D(int y)435*67e74705SXin Li int f24_D(int y) {
436*67e74705SXin Li   __block int x = (y > 2); // no-warning
437*67e74705SXin Li   ^{
438*67e74705SXin Li     if (y > 4)
439*67e74705SXin Li       x = 5; // no-warning
440*67e74705SXin Li   }();
441*67e74705SXin Li   return x;
442*67e74705SXin Li }
443*67e74705SXin Li 
444*67e74705SXin Li // This example shows that writing to a variable captured by a block means that it might
445*67e74705SXin Li // not be dead.
f25(int y)446*67e74705SXin Li int f25(int y) {
447*67e74705SXin Li   __block int x = (y > 2);
448*67e74705SXin Li   __block int z = 0;
449*67e74705SXin Li   void (^foo)() = ^{ z = x + y; };
450*67e74705SXin Li   x = 4; // no-warning
451*67e74705SXin Li   foo();
452*67e74705SXin Li   return z;
453*67e74705SXin Li }
454*67e74705SXin Li 
455*67e74705SXin Li // This test is mostly the same as 'f25', but shows that the heuristic of pruning out dead
456*67e74705SXin Li // stores for variables that are just marked '__block' is overly conservative.
f25_b(int y)457*67e74705SXin Li int f25_b(int y) {
458*67e74705SXin Li   // FIXME: we should eventually report a dead store here.
459*67e74705SXin Li   __block int x = (y > 2);
460*67e74705SXin Li   __block int z = 0;
461*67e74705SXin Li   x = 4; // no-warning
462*67e74705SXin Li   return z;
463*67e74705SXin Li }
464*67e74705SXin Li 
f26_nestedblocks()465*67e74705SXin Li int f26_nestedblocks() {
466*67e74705SXin Li   int z;
467*67e74705SXin Li   z = 1;
468*67e74705SXin Li   __block int y = 0;
469*67e74705SXin Li   ^{
470*67e74705SXin Li     int k;
471*67e74705SXin Li     k = 1; // expected-warning{{Value stored to 'k' is never read}}
472*67e74705SXin Li     ^{
473*67e74705SXin Li         y = z + 1;
474*67e74705SXin Li      }();
475*67e74705SXin Li   }();
476*67e74705SXin Li   return y;
477*67e74705SXin Li }
478*67e74705SXin Li 
479*67e74705SXin Li // The FOREACH macro in QT uses 'break' statements within statement expressions
480*67e74705SXin Li // placed within the increment code of for loops.
rdar8014335()481*67e74705SXin Li void rdar8014335() {
482*67e74705SXin Li   for (int i = 0 ; i != 10 ; ({ break; })) {
483*67e74705SXin Li     for ( ; ; ({ ++i; break; })) ; // expected-warning {{'break' is bound to current loop, GCC binds it to the enclosing loop}}
484*67e74705SXin Li     // Note that the next value stored to 'i' is never executed
485*67e74705SXin Li     // because the next statement to be executed is the 'break'
486*67e74705SXin Li     // in the increment code of the first loop.
487*67e74705SXin Li     i = i * 3; // expected-warning{{Value stored to 'i' is never read}}
488*67e74705SXin Li   }
489*67e74705SXin Li }
490*67e74705SXin Li 
491*67e74705SXin Li // <rdar://problem/8320674> NullStmts followed by do...while() can lead to disconnected CFG
492*67e74705SXin Li //
493*67e74705SXin Li // This previously caused bogus dead-stores warnings because the body of the first do...while was
494*67e74705SXin Li // disconnected from the entry of the function.
495*67e74705SXin Li typedef struct { float r; float i; } s_rdar8320674;
496*67e74705SXin Li typedef struct { s_rdar8320674 x[1]; } s2_rdar8320674;
497*67e74705SXin Li 
rdar8320674(s_rdar8320674 * z,unsigned y,s2_rdar8320674 * st,int m)498*67e74705SXin Li void rdar8320674(s_rdar8320674 *z, unsigned y, s2_rdar8320674 *st, int m)
499*67e74705SXin Li {
500*67e74705SXin Li     s_rdar8320674 * z2;
501*67e74705SXin Li     s_rdar8320674 * tw1 = st->x;
502*67e74705SXin Li     s_rdar8320674 t;
503*67e74705SXin Li     z2 = z + m;
504*67e74705SXin Li     do{
505*67e74705SXin Li         ; ;
506*67e74705SXin Li         do{ (t).r = (*z2).r*(*tw1).r - (*z2).i*(*tw1).i; (t).i = (*z2).r*(*tw1).i + (*z2).i*(*tw1).r; }while(0);
507*67e74705SXin Li         tw1 += y;
508*67e74705SXin Li         do { (*z2).r=(*z).r-(t).r; (*z2).i=(*z).i-(t).i; }while(0);
509*67e74705SXin Li         do { (*z).r += (t).r; (*z).i += (t).i; }while(0);
510*67e74705SXin Li         ++z2;
511*67e74705SXin Li         ++z;
512*67e74705SXin Li     }while (--m);
513*67e74705SXin Li }
514*67e74705SXin Li 
515*67e74705SXin Li // Avoid dead stores resulting from an assignment (and use) being unreachable.
516*67e74705SXin Li void rdar8405222_aux(int i);
rdar8405222()517*67e74705SXin Li void rdar8405222() {
518*67e74705SXin Li   const int show = 0;
519*67e74705SXin Li   int i = 0;
520*67e74705SXin Li 
521*67e74705SXin Li   if (show)
522*67e74705SXin Li       i = 5; // no-warning
523*67e74705SXin Li 
524*67e74705SXin Li   if (show)
525*67e74705SXin Li     rdar8405222_aux(i);
526*67e74705SXin Li }
527*67e74705SXin Li 
528*67e74705SXin Li // Look through chains of assignements, e.g.: int x = y = 0, when employing
529*67e74705SXin Li // silencing heuristics.
radar11185138_foo()530*67e74705SXin Li int radar11185138_foo() {
531*67e74705SXin Li   int x, y;
532*67e74705SXin Li   x = y = 0; // expected-warning {{never read}}
533*67e74705SXin Li   return y;
534*67e74705SXin Li }
535*67e74705SXin Li 
rdar11185138_bar()536*67e74705SXin Li int rdar11185138_bar() {
537*67e74705SXin Li   int y;
538*67e74705SXin Li   int x = y = 0; // no-warning
539*67e74705SXin Li   x = 2;
540*67e74705SXin Li   y = 2;
541*67e74705SXin Li   return x + y;
542*67e74705SXin Li }
543*67e74705SXin Li 
radar11185138_baz()544*67e74705SXin Li int *radar11185138_baz() {
545*67e74705SXin Li   int *x, *y;
546*67e74705SXin Li   x = y = 0; // no-warning
547*67e74705SXin Li   return y;
548*67e74705SXin Li }
549*67e74705SXin Li 
550*67e74705SXin Li int getInt();
551*67e74705SXin Li int *getPtr();
testBOComma()552*67e74705SXin Li void testBOComma() {
553*67e74705SXin Li   int x0 = (getInt(), 0); // expected-warning{{unused variable 'x0'}}
554*67e74705SXin Li   int x1 = (getInt(), getInt()); // expected-warning {{Value stored to 'x1' during its initialization is never read}} // expected-warning{{unused variable 'x1'}}
555*67e74705SXin Li   int x2 = (getInt(), getInt(), getInt()); //expected-warning{{Value stored to 'x2' during its initialization is never read}} // expected-warning{{unused variable 'x2'}}
556*67e74705SXin Li   int x3;
557*67e74705SXin Li   x3 = (getInt(), getInt(), 0); // expected-warning{{Value stored to 'x3' is never read}}
558*67e74705SXin Li   int x4 = (getInt(), (getInt(), 0)); // expected-warning{{unused variable 'x4'}}
559*67e74705SXin Li   int y;
560*67e74705SXin Li   int x5 = (getInt(), (y = 0)); // expected-warning{{unused variable 'x5'}}
561*67e74705SXin Li   int x6 = (getInt(), (y = getInt())); //expected-warning {{Value stored to 'x6' during its initialization is never read}} // expected-warning{{unused variable 'x6'}}
562*67e74705SXin Li   int x7 = 0, x8 = getInt(); //expected-warning {{Value stored to 'x8' during its initialization is never read}} // expected-warning{{unused variable 'x8'}} // expected-warning{{unused variable 'x7'}}
563*67e74705SXin Li   int x9 = getInt(), x10 = 0; //expected-warning {{Value stored to 'x9' during its initialization is never read}} // expected-warning{{unused variable 'x9'}}  // expected-warning{{unused variable 'x10'}}
564*67e74705SXin Li   int m = getInt(), mm, mmm; //expected-warning {{Value stored to 'm' during its initialization is never read}} // expected-warning{{unused variable 'm'}} // expected-warning{{unused variable 'mm'}} // expected-warning{{unused variable 'mmm'}}
565*67e74705SXin Li   int n, nn = getInt(); //expected-warning {{Value stored to 'nn' during its initialization is never read}} // expected-warning{{unused variable 'n'}} // expected-warning{{unused variable 'nn'}}
566*67e74705SXin Li 
567*67e74705SXin Li   int *p;
568*67e74705SXin Li   p = (getPtr(), (int *)0); // no warning
569*67e74705SXin Li 
570*67e74705SXin Li }
571*67e74705SXin Li 
testVolatile()572*67e74705SXin Li void testVolatile() {
573*67e74705SXin Li     volatile int v;
574*67e74705SXin Li     v = 0; // no warning
575*67e74705SXin Li }
576