brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.0 KiB · 00b19b1 Raw
677 lines · c
1// RUN: %check_analyzer_fixit %s %t \2// RUN:   -Wunused-variable -fblocks -Wno-unreachable-code \3// RUN:   -analyzer-checker=core,deadcode.DeadStores \4// RUN:   -analyzer-config deadcode.DeadStores:ShowFixIts=true \5// RUN:   -analyzer-config \6// RUN:       deadcode.DeadStores:WarnForDeadNestedAssignments=false \7// RUN:   -verify=non-nested8 9// RUN: %check_analyzer_fixit %s %t \10// RUN:   -Wunused-variable -fblocks -Wno-unreachable-code \11// RUN:   -analyzer-checker=core,deadcode.DeadStores \12// RUN:   -analyzer-config deadcode.DeadStores:ShowFixIts=true \13// RUN:   -verify=non-nested,nested14 15extern int printf(const char *, ...);16 17void f1(void) {18  int k, y; // non-nested-warning {{unused variable 'k'}}19            // non-nested-warning@-1 {{unused variable 'y'}}20  int abc = 1;21  long idx = abc + 3 * 5; // non-nested-warning {{never read}}22                          // non-nested-warning@-1 {{unused variable 'idx'}}23  // CHECK-FIXES:      int abc = 1;24  // CHECK-FIXES-NEXT: long idx;25}26 27void f2(void *b) {28  char *c = (char *)b; // no-warning29  char *d = b + 1;     // non-nested-warning {{never read}}30                       // non-nested-warning@-1 {{unused variable 'd'}}31  // CHECK-FIXES:      char *c = (char *)b;32  // CHECK-FIXES-NEXT: char *d;33 34  printf("%s", c);35}36 37int f(void);38void f3(void) {39  int r;40  if ((r = f()) != 0) { // no-warning41    int y = r;          // no-warning42    printf("the error is: %d\n", y);43  }44}45 46void f4(int k) {47  k = 1;48  if (k)49    f1();50  k = 2; // non-nested-warning {{never read}}51}52 53void f5(void) {54  int x = 4;   // no-warning55  int *p = &x; // non-nested-warning {{never read}}56               // non-nested-warning@-1 {{unused variable 'p'}}57  // CHECK-FIXES:      int x = 4;58  // CHECK-FIXES-NEXT: int *p;59}60 61int f6(void) {62  int x = 4;63  ++x; // no-warning64  return 1;65}66 67int f7(int *p) {68  // This is allowed for defensive programming.69  p = 0; // no-warning70  return 1;71}72 73int f7b(int *p) {74  // This is allowed for defensive programming.75  p = (0); // no-warning76  return 1;77}78 79int f7c(int *p) {80  // This is allowed for defensive programming.81  p = (void *)0; // no-warning82  return 1;83}84 85int f7d(int *p) {86  // This is allowed for defensive programming.87  p = (void *)(0); // no-warning88  return 1;89}90 91// Warn for dead stores in nested expressions.92int f8(int *p) {93  extern int *baz(void);94  if ((p = baz())) // nested-warning {{Although the value stored}}95    return 1;96  return 0;97}98 99int f9(void) {100  int x = 4;101  x = x + 10; // non-nested-warning {{never read}}102  return 1;103}104 105int f10(void) {106  int x = 4;107  x = 10 + x; // non-nested-warning {{never read}}108  return 1;109}110 111int f11(void) {112  int x = 4;113  return x++; // non-nested-warning {{never read}}114}115 116int f11b(void) {117  int x = 4;118  return ((((++x)))); // no-warning119}120 121int f12a(int y) {122  int x = y; // non-nested-warning {{unused variable 'x'}}123  return 1;124}125 126int f12b(int y) {127  int x __attribute__((unused)) = y; // no-warning128  return 1;129}130 131int f12c(int y) {132  // Allow initialiation of scalar variables by parameters as a form of133  // defensive programming.134  int x = y; // no-warning135  x = 1;136  return x;137}138 139// Filed with PR 2630.  This code should produce no warnings.140int f13(void) {141  int a = 1;142  int b, c = b = a + a;143 144  if (b > 0)145    return (0);146  return (a + b + c);147}148 149// Filed with PR 2763.150int f14(int count) {151  int index, nextLineIndex;152  for (index = 0; index < count; index = nextLineIndex + 1) {153    nextLineIndex = index + 1; // no-warning154    continue;155  }156  return index;157}158 159void f15(unsigned x, unsigned y) {160  int count = x * y; // no-warning161  int z[count];      // non-nested-warning {{unused variable 'z'}}162}163 164// Warn for dead stores in nested expressions.165int f16(int x) {166  x = x * 2;167  x = sizeof(int[x = (x || x + 1) * 2]) ? 5 : 8;168  // nested-warning@-1 {{Although the value stored}}169  return x;170}171 172// Self-assignments should not be flagged as dead stores.173void f17(void) {174  int x = 1;175  x = x;176}177 178// The values of dead stores are only "consumed" in an enclosing expression179// what that value is actually used.  In other words, don't say "Although the180// value stored to 'x' is used...".181int f18(void) {182  int x = 0; // no-warning183  if (1)184    x = 10; // non-nested-warning {{Value stored to 'x' is never read}}185  while (1)186    x = 10; // non-nested-warning {{Value stored to 'x' is never read}}187  // unreachable.188  do189    x = 10; // no-warning190  while (1);191  return (x = 10); // no-warning192}193 194int f18_a(void) {195  int x = 0;       // no-warning196  return (x = 10); // nested-warning {{Although the value stored}}197}198 199void f18_b(void) {200  int x = 0; // no-warning201  if (1)202    x = 10; // non-nested-warning {{Value stored to 'x' is never read}}203}204 205void f18_c(void) {206  int x = 0;207  while (1)208    x = 10; // non-nested-warning {{Value stored to 'x' is never read}}209}210 211void f18_d(void) {212  int x = 0; // no-warning213  do214    x = 10; // non-nested-warning {{Value stored to 'x' is never read}}215  while (1);216}217 218// PR 3514: false positive `dead initialization` warning for init to global219//  http://llvm.org/bugs/show_bug.cgi?id=3514220extern const int MyConstant;221int f19(void) {222  int x = MyConstant; // no-warning223  x = 1;224  return x;225}226 227int f19b(void) { // This case is the same as f19.228  const int MyConstant = 0;229  int x = MyConstant; // no-warning230  x = 1;231  return x;232}233 234void f20(void) {235  int x = 1; // no-warning236#pragma unused(x)237}238 239void halt(void) __attribute__((noreturn));240int f21(void) {241  int x = 4;242  x = x + 1; // non-nested-warning {{never read}}243  if (1) {244    halt();245    (void)x;246  }247  return 1;248}249 250int j;251void f22(void) {252  int x = 4;253  int y1 = 4;254  int y2 = 4;255  int y3 = 4;256  int y4 = 4;257  int y5 = 4;258  int y6 = 4;259  int y7 = 4;260  int y8 = 4;261  int y9 = 4;262  int y10 = 4;263  int y11 = 4;264  int y12 = 4;265  int y13 = 4;266  int y14 = 4;267  int y15 = 4;268  int y16 = 4;269  int y17 = 4;270  int y18 = 4;271  int y19 = 4;272  int y20 = 4;273 274  x = x + 1; // non-nested-warning {{never read}}275  ++y1;276  ++y2;277  ++y3;278  ++y4;279  ++y5;280  ++y6;281  ++y7;282  ++y8;283  ++y9;284  ++y10;285  ++y11;286  ++y12;287  ++y13;288  ++y14;289  ++y15;290  ++y16;291  ++y17;292  ++y18;293  ++y19;294  ++y20;295 296  switch (j) {297  case 1:298    if (0)299      (void)x;300    if (1) {301      (void)y1;302      return;303    }304    (void)x;305    break;306  case 2:307    if (0)308      (void)x;309    else {310      (void)y2;311      return;312    }313    (void)x;314    break;315  case 3:316    if (1) {317      (void)y3;318      return;319    } else320      (void)x;321    (void)x;322    break;323  case 4:324    0 ?: ((void)y4, ({ return; }));325    (void)x;326    break;327  case 5:328    1 ?: (void)x;329    0 ? (void)x : ((void)y5, ({ return; }));330    (void)x;331    break;332  case 6:333    1 ? ((void)y6, ({ return; })) : (void)x;334    (void)x;335    break;336  case 7:337    (void)(0 && x);338    (void)y7;339    (void)(0 || (y8, ({ return; }), 1));340    // non-nested-warning@-1 {{left operand of comma operator has no effect}}341    (void)x;342    break;343  case 8:344    (void)(1 && (y9, ({ return; }), 1));345    // non-nested-warning@-1 {{left operand of comma operator has no effect}}346    (void)x;347    break;348  case 9:349    (void)(1 || x);350    (void)y10;351    break;352  case 10:353    while (0) {354      (void)x;355    }356    (void)y11;357    break;358  case 11:359    while (1) {360      (void)y12;361    }362    (void)x;363    break;364  case 12:365    do {366      (void)y13;367    } while (0);368    (void)y14;369    break;370  case 13:371    do {372      (void)y15;373    } while (1);374    (void)x;375    break;376  case 14:377    for (;;) {378      (void)y16;379    }380    (void)x;381    break;382  case 15:383    for (; 1;) {384      (void)y17;385    }386    (void)x;387    break;388  case 16:389    for (; 0;) {390      (void)x;391    }392    (void)y18;393    break;394  case 17:395    __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));396    (void)x;397    break;398  case 19:399    __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);400    (void)x;401    break;402  }403}404 405void f23_aux(const char *s);406void f23(int argc, char **argv) {407  int shouldLog = (argc > 1); // no-warning408  ^{409    if (shouldLog)410      f23_aux("I did too use it!\n");411    else412      f23_aux("I shouldn't log.  Wait.. d'oh!\n");413  }();414}415 416void f23_pos(int argc, char **argv) {417  int shouldLog = (argc > 1);418  // non-nested-warning@-1 {{Value stored to 'shouldLog' during its initialization is never read}}419  // non-nested-warning@-2 {{unused variable 'shouldLog'}}420  // CHECK-FIXES:      void f23_pos(int argc, char **argv) {421  // CHECK-FIXES-NEXT:   int shouldLog;422  ^{423    f23_aux("I did too use it!\n");424  }();425}426 427void f24_A(int y) {428  // FIXME: One day this should be reported as dead since 'z = x + y' is dead.429  int x = (y > 2); // no-warning430  ^{431    int z = x + y;432    // non-nested-warning@-1 {{Value stored to 'z' during its initialization is never read}}433    // non-nested-warning@-2 {{unused variable 'z'}}434    // CHECK-FIXES:      void f24_A(int y) {435    // CHECK-FIXES-NEXT:   //436    // CHECK-FIXES-NEXT:   int x = (y > 2);437    // CHECK-FIXES-NEXT:   ^{438    // CHECK-FIXES-NEXT:     int z;439  }();440}441 442void f24_B(int y) {443  // FIXME: One day this should be reported as dead since 'x' is just overwritten.444  __block int x = (y > 2); // no-warning445  ^{446    // FIXME: This should eventually be a dead store since it is never read either.447    x = 5; // no-warning448  }();449}450 451int f24_C(int y) {452  // FIXME: One day this should be reported as dead since 'x' is just overwritten.453  __block int x = (y > 2); // no-warning454  ^{455    x = 5; // no-warning456  }();457  return x;458}459 460int f24_D(int y) {461  __block int x = (y > 2); // no-warning462  ^{463    if (y > 4)464      x = 5; // no-warning465  }();466  return x;467}468 469// This example shows that writing to a variable captured by a block means that470// it might not be dead.471int f25(int y) {472  __block int x = (y > 2);473  __block int z = 0;474  void (^foo)(void) = ^{475    z = x + y;476  };477  x = 4; // no-warning478  foo();479  return z;480}481 482// This test is mostly the same as 'f25', but shows that the heuristic of483// pruning out dead stores for variables that are just marked '__block' is484// overly conservative.485int f25_b(int y) {486  // FIXME: we should eventually report a dead store here.487  __block int x = (y > 2);488  __block int z = 0;489  x = 4; // no-warning490  return z;491}492 493int f26_nestedblocks(void) {494  int z;495  z = 1;496  __block int y = 0;497  ^{498    int k;499    k = 1; // non-nested-warning {{Value stored to 'k' is never read}}500    ^{501      y = z + 1;502    }();503  }();504  return y;505}506 507// The FOREACH macro in QT uses 'break' statements within statement expressions508// placed within the increment code of for loops.509void rdar8014335(void) {510  for (int i = 0 ; i != 10 ; ({ break; })) {511    for (;; ({ ++i; break; }))512      ;513    // non-nested-warning@-2 {{'break' is bound to current loop, GCC binds it to the enclosing loop}}514    // Note that the next value stored to 'i' is never executed515    // because the next statement to be executed is the 'break'516    // in the increment code of the first loop.517    i = i * 3; // non-nested-warning {{Value stored to 'i' is never read}}518  }519}520 521// NullStmts followed by do...while() can lead to disconnected CFG522//523// This previously caused bogus dead-stores warnings because the body of the first do...while was524// disconnected from the entry of the function.525typedef struct { float r; float i; } s_rdar8320674;526typedef struct { s_rdar8320674 x[1]; } s2_rdar8320674;527 528void rdar8320674(s_rdar8320674 *z, unsigned y, s2_rdar8320674 *st, int m)529{530    s_rdar8320674 * z2;531    s_rdar8320674 * tw1 = st->x;532    s_rdar8320674 t;533    z2 = z + m;534    do{535        ; ;536        do{ (t).r = (*z2).r*(*tw1).r - (*z2).i*(*tw1).i; (t).i = (*z2).r*(*tw1).i + (*z2).i*(*tw1).r; }while(0);537        tw1 += y;538        do { (*z2).r=(*z).r-(t).r; (*z2).i=(*z).i-(t).i; }while(0);539        do { (*z).r += (t).r; (*z).i += (t).i; }while(0);540        ++z2;541        ++z;542    }while (--m);543}544 545// Avoid dead stores resulting from an assignment (and use) being unreachable.546void rdar8405222_aux(int i);547void rdar8405222(void) {548  const int show = 0;549  int i = 0;550  if (show)551    i = 5; // no-warning552  if (show)553    rdar8405222_aux(i);554}555 556// Look through chains of assignments, e.g.: int x = y = 0, when employing557// silencing heuristics.558int radar11185138_foo(void) {559  int x, y;560  x = y = 0; // non-nested-warning {{never read}}561  return y;562}563 564int rdar11185138_bar(void) {565  int y;566  int x = y = 0; // nested-warning {{Although the value stored}}567  x = 2;568  y = 2;569  return x + y;570}571 572int *radar11185138_baz(void) {573  int *x, *y;574  x = y = 0; // no-warning575  return y;576}577 578int getInt(void);579int *getPtr(void);580void testBOComma(void) {581  int x0 = (getInt(), 0); // non-nested-warning {{unused variable 'x0'}}582  int x1 = (getInt(), getInt());583  // non-nested-warning@-1 {{Value stored to 'x1' during its initialization is never read}}584  // non-nested-warning@-2 {{unused variable 'x1'}}585 586  int x2 = (getInt(), getInt(), getInt());587  // non-nested-warning@-1 {{Value stored to 'x2' during its initialization is never read}}588  // non-nested-warning@-2 {{unused variable 'x2'}}589 590  int x3;591  x3 = (getInt(), getInt(), 0);592  // non-nested-warning@-1 {{Value stored to 'x3' is never read}}593 594  int x4 = (getInt(), (getInt(), 0));595  // non-nested-warning@-1 {{unused variable 'x4'}}596 597  int y;598  int x5 = (getInt(), (y = 0));599  // non-nested-warning@-1 {{unused variable 'x5'}}600  // nested-warning@-2 {{Although the value stored}}601 602  int x6 = (getInt(), (y = getInt()));603  // non-nested-warning@-1 {{Value stored to 'x6' during its initialization is never read}}604  // non-nested-warning@-2 {{unused variable 'x6'}}605  // nested-warning@-3 {{Although the value stored}}606 607  int x7 = 0, x8 = getInt();608  // non-nested-warning@-1 {{Value stored to 'x8' during its initialization is never read}}609  // non-nested-warning@-2 {{unused variable 'x8'}}610  // non-nested-warning@-3 {{unused variable 'x7'}}611 612  int x9 = getInt(), x10 = 0;613  // non-nested-warning@-1 {{Value stored to 'x9' during its initialization is never read}}614  // non-nested-warning@-2 {{unused variable 'x9'}}615  // non-nested-warning@-3 {{unused variable 'x10'}}616 617  int m = getInt(), mm, mmm;618  // non-nested-warning@-1 {{Value stored to 'm' during its initialization is never read}}619  // non-nested-warning@-2 {{unused variable 'm'}}620  // non-nested-warning@-3 {{unused variable 'mm'}}621  // non-nested-warning@-4 {{unused variable 'mmm'}}622 623  int n, nn = getInt();624  // non-nested-warning@-1 {{Value stored to 'nn' during its initialization is never read}}625  // non-nested-warning@-2 {{unused variable 'n'}}626  // non-nested-warning@-3 {{unused variable 'nn'}}627 628  int *p;629  p = (getPtr(), (int *)0); // no warning630}631 632void testVolatile(void) {633  volatile int v;634  v = 0; // no warning635}636 637struct Foo {638  int x;639  int y;640};641 642struct Foo rdar34122265_getFoo(void);643 644int rdar34122265_test(int input) {645  // This is allowed for defensive programming.646  struct Foo foo = {0, 0};647  if (input > 0) {648    foo = rdar34122265_getFoo();649  } else {650    return 0;651  }652  return foo.x + foo.y;653}654 655void rdar34122265_test_cast(void) {656  // This is allowed for defensive programming.657  struct Foo foo = {0, 0};658  (void)foo;659}660 661struct Bar {662  struct Foo x, y;663};664 665struct Bar rdar34122265_getBar(void);666 667int rdar34122265_test_nested(int input) {668  // This is allowed for defensive programming.669  struct Bar bar = {{0, 0}, {0, 0}};670  if (input > 0) {671    bar = rdar34122265_getBar();672  } else {673    return 0;674  }675  return bar.x.x + bar.y.y;676}677