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