Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.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,alpha.deadcode.IdempotentOperations -analyzer-store=region -analyzer-constraints=range -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
      3 
      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 
     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{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
     15 }
     16 
     17 int f();
     18 
     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 
     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 
     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 //
     45 int f6() {
     46 
     47   int x = 4;
     48   ++x; // no-warning
     49   return 1;
     50 }
     51 
     52 int f7(int *p) {
     53   // This is allowed for defensive programming.
     54   p = 0; // no-warning
     55   return 1;
     56 }
     57 
     58 int f7b(int *p) {
     59   // This is allowed for defensive programming.
     60   p = (0); // no-warning
     61   return 1;
     62 }
     63 
     64 int f7c(int *p) {
     65   // This is allowed for defensive programming.
     66   p = (void*) 0; // no-warning
     67   return 1;
     68 }
     69 
     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.
     78 int f8(int *p) {
     79   extern int *baz();
     80   if ((p = baz())) // no-warning
     81     return 1;
     82   return 0;
     83 }
     84 
     85 int f9() {
     86   int x = 4;
     87   x = x + 10; // expected-warning{{never read}}
     88   return 1;
     89 }
     90 
     91 int f10() {
     92   int x = 4;
     93   x = 10 + x; // expected-warning{{never read}}
     94   return 1;
     95 }
     96 
     97 int f11() {
     98   int x = 4;
     99   return x++; // expected-warning{{never read}}
    100 }
    101 
    102 int f11b() {
    103   int x = 4;
    104   return ((((++x)))); // no-warning
    105 }
    106 
    107 int f12a(int y) {
    108   int x = y;  // expected-warning{{unused variable 'x'}}
    109   return 1;
    110 }
    111 int f12b(int y) {
    112   int x __attribute__((unused)) = y;  // no-warning
    113   return 1;
    114 }
    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.
    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.
    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>
    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.
    153 int f16(int x) {
    154   x = x * 2;
    155   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}}
    156       ? 5 : 8;
    157   return x;
    158 }
    159 
    160 // Self-assignments should not be flagged as dead stores.
    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...".
    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 
    183 int f18_a() {
    184    int x = 0; // no-warning
    185    return (x = 10); // no-warning
    186 }
    187 
    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 
    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 
    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;
    210 int f19(void) {
    211   int x = MyConstant;  // no-warning
    212   x = 1;
    213   return x;
    214 }
    215 
    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 
    223 void f20(void) {
    224   int x = 1; // no-warning
    225 #pragma unused(x)
    226 }
    227 
    228 void halt() __attribute__((noreturn));
    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;
    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);
    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 
    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 
    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 
    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 
    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 
    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.
    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.
    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 
    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.
    481 void rdar8014335() {
    482   for (int i = 0 ; i != 10 ; ({ break; })) {
    483     for ( ; ; ({ ++i; break; })) ;
    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}} expected-warning{{The left operand to '*' is always 1}}
    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 
    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);
    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.
    530 int radar11185138_foo() {
    531   int x, y;
    532   x = y = 0; // expected-warning {{never read}}
    533   return y;
    534 }
    535 
    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 
    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();
    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