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