brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.4 KiB · 17e83de Raw
586 lines · c
1// RUN: %clang_cc1 -Wuninitialized -Wconditional-uninitialized -fsyntax-only -fblocks %s -verify2// RUN: %clang_cc1 -Wuninitialized -Wconditional-uninitialized -ftrivial-auto-var-init=pattern -fsyntax-only -fblocks %s -verify3 4typedef __typeof(sizeof(int)) size_t;5void *malloc(size_t);6 7int test1(void) {8  int x; // expected-note{{initialize the variable 'x' to silence this warning}}9  return x; // expected-warning{{variable 'x' is uninitialized when used here}}10}11 12int test2(void) {13  int x = 0;14  return x; // no-warning15}16 17int test3(void) {18  int x;19  x = 0;20  return x; // no-warning21}22 23int test4(void) {24  int x; // expected-note{{initialize the variable 'x' to silence this warning}}25  ++x; // expected-warning{{variable 'x' is uninitialized when used here}}26  return x; 27}28 29int test5(void) {30  int x, y; // expected-note{{initialize the variable 'y' to silence this warning}}31  x = y; // expected-warning{{variable 'y' is uninitialized when used here}}32  return x;33}34 35int test6(void) {36  int x; // expected-note{{initialize the variable 'x' to silence this warning}}37  x += 2; // expected-warning{{variable 'x' is uninitialized when used here}}38  return x;39}40 41int test7(int y) {42  int x; // expected-note{{initialize the variable 'x' to silence this warning}}43  if (y) // expected-warning{{variable 'x' is used uninitialized whenever 'if' condition is false}} \44         // expected-note{{remove the 'if' if its condition is always true}}45    x = 1;46  return x; // expected-note{{uninitialized use occurs here}}47}48 49int test7b(int y) {50  int x = x; // expected-note{{variable 'x' is declared here}}51  if (y)52    x = 1;53  // Warn with "may be uninitialized" here (not "is sometimes uninitialized"),54  // since the self-initialization is intended to suppress a -Wuninitialized55  // warning.56  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}57}58 59int test8(int y) {60  int x;61  if (y)62    x = 1;63  else64    x = 0;65  return x;66}67 68int test9(int n) {69  int x; // expected-note{{initialize the variable 'x' to silence this warning}}70  for (unsigned i = 0 ; i < n; ++i) {71    if (i == n - 1)72      break;73    x = 1;74  }75  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}76}77 78int test10(unsigned n) {79  int x; // expected-note{{initialize the variable 'x' to silence this warning}}80  for (unsigned i = 0 ; i < n; ++i) {81    x = 1;82  }83  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}84}85 86int test11(unsigned n) {87  int x; // expected-note{{initialize the variable 'x' to silence this warning}}88  for (unsigned i = 0 ; i <= n; ++i) {89    x = 1;90  }91  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}92}93 94void test12(unsigned n) {95  for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is uninitialized when used here}} expected-note{{initialize the variable 'i' to silence this warning}}96}97 98int test13(void) {99  static int i;100  return i; // no-warning101}102 103// Simply don't crash on this test case.104void test14(void) {105  const char *p = 0;106  for (;;) {}107}108 109void test15(void) {110  int x = x; // no-warning: signals intended lack of initialization.111}112 113int test15b(void) {114  // Warn here with the self-init, since it does result in a use of115  // an uninitialized variable and this is the root cause.116  int x = x; // expected-warning {{variable 'x' is uninitialized when used within its own initialization}}117  return x;118}119 120// Don't warn in the following example; shows dataflow confluence.121char *test16_aux(void);122void test16(void) {123  char *p = test16_aux();124  for (unsigned i = 0 ; i < 100 ; i++)125    p[i] = 'a'; // no-warning126}127 128void test17(void) {129  // Don't warn multiple times about the same uninitialized variable130  // along the same path.131  int *x; // expected-note{{initialize the variable 'x' to silence this warning}}132  *x = 1; // expected-warning{{variable 'x' is uninitialized when used here}}133  *x = 1; // no-warning134}135 136int test18(int x, int y) {137  int z;138  if (x && y && (z = 1)) {139    return z; // no-warning140  }141  return 0;142}143 144int test19_aux1(void);145int test19_aux2(void);146int test19_aux3(int *x);147int test19(void) {148  int z;149  if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))150    return z; // no-warning151  return 0;152}153 154int test20(void) {155  int z; // expected-note{{initialize the variable 'z' to silence this warning}}156  if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}}157    return z; // expected-note {{uninitialized use occurs here}}158  return 0;159}160 161int test21(int x, int y) {162  int z; // expected-note{{initialize the variable 'z' to silence this warning}}163  if ((x && y) || test19_aux3(&z) || test19_aux2()) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}}164    return z; // expected-note {{uninitialized use occurs here}}165  return 0;166}167 168int test22(void) {169  int z;170  while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))171    return z; // no-warning172  return 0;173}174 175int test23(void) {176  int z;177  for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; )178    return z; // no-warning179  return 0;180}181 182// The basic uninitialized value analysis doesn't have enough path-sensitivity183// to catch initializations relying on control-dependencies spanning multiple184// conditionals.  This possibly can be handled by making the CFG itself185// represent such control-dependencies, but it is a niche case.186int test24(int flag) {187  unsigned val; // expected-note{{initialize the variable 'val' to silence this warning}}188  if (flag)189    val = 1;190  if (!flag)191    val = 1;192  return val; // expected-warning{{variable 'val' may be uninitialized when used here}}193}194 195float test25(void) {196  float x; // expected-note{{initialize the variable 'x' to silence this warning}}197  return x; // expected-warning{{variable 'x' is uninitialized when used here}}198}199 200typedef int MyInt;201MyInt test26(void) {202  MyInt x; // expected-note{{initialize the variable 'x' to silence this warning}}203  return x; // expected-warning{{variable 'x' is uninitialized when used here}}204}205 206// Test handling of sizeof().207int test27(void) {208  struct test_27 { int x; } *y;209  return sizeof(y->x); // no-warning210}211 212int test28(void) {213  int len; // expected-note{{initialize the variable 'len' to silence this warning}}214  return sizeof(int[len]); // expected-warning{{variable 'len' is uninitialized when used here}}215}216 217void test29(void) {218  int x; // expected-note{{initialize the variable 'x' to silence this warning}}219  (void) ^{ (void) x; }; // expected-warning{{variable 'x' is uninitialized when captured by block}}220}221 222void test30(void) {223  static int x; // no-warning224  (void) ^{ (void) x; };225}226 227void test31(void) {228  __block int x; // no-warning229  (void) ^{ (void) x; };230}231 232int test32_x;233void test32(void) {234  (void) ^{ (void) test32_x; }; // no-warning235}236 237void test_33(void) {238  int x; // no-warning239  (void) x;240}241 242int test_34(void) {243  int x; // expected-note{{initialize the variable 'x' to silence this warning}}244  (void) x;245  return x; // expected-warning{{variable 'x' is uninitialized when used here}}246}247 248// Test that this case doesn't crash.249void test35(int x) {250  __block int y = 0;251  ^{ y = (x == 0); }();252}253 254// Test handling of indirect goto.255void test36(void)256{257  void **pc; // expected-note{{initialize the variable 'pc' to silence this warning}}258  void *dummy[] = { &&L1, &&L2 };259 L1:260    goto *pc; // expected-warning{{variable 'pc' is uninitialized when used here}}261 L2:262    goto *pc;263}264 265// Test && nested in ||.266int test37_a(void);267int test37_b(void);268int test37(void)269{270    int identifier;271    if ((test37_a() && (identifier = 1)) ||272        (test37_b() && (identifier = 2))) {273        return identifier; // no-warning274    }275    return 0;276}277 278// Test merging of path-specific dataflow values (without asserting).279int test38(int r, int x, int y)280{281  int z;282  return ((r < 0) || ((r == 0) && (x < y)));283}284 285int test39(int x) {286  int y; // expected-note{{initialize the variable 'y' to silence this warning}}287  int z = x + y; // expected-warning {{variable 'y' is uninitialized when used here}}288  return z;289}290 291 292int test40(int x) {293  int y; // expected-note{{initialize the variable 'y' to silence this warning}}294  return x ? 1 : y; // expected-warning {{variable 'y' is uninitialized when used here}}295}296 297int test41(int x) {298  int y; // expected-note{{initialize the variable 'y' to silence this warning}}299  if (x) y = 1; // expected-warning{{variable 'y' is used uninitialized whenever 'if' condition is false}} \300                // expected-note{{remove the 'if' if its condition is always true}}301  return y; // expected-note{{uninitialized use occurs here}}302}303 304void test42(void) {305  int a;306  a = 30; // no-warning307}308 309void test43_aux(int x);310void test43(int i) {311  int x; // expected-note{{initialize the variable 'x' to silence this warning}}312  for (i = 0 ; i < 10; i++)313    test43_aux(x++); // expected-warning {{variable 'x' is uninitialized when used here}}314}315 316void test44(int i) {317  int x = i;318  int y; // expected-note{{initialize the variable 'y' to silence this warning}}319  for (i = 0; i < 10; i++ ) {320    test43_aux(x++); // no-warning321    x += y; // expected-warning {{variable 'y' is uninitialized when used here}}322  }323}324 325int test45(int j) {326  int x = 1, y = x + 1;327  if (y) // no-warning328    return x;329  return y;330}331 332void test46(void)333{334  int i; // expected-note{{initialize the variable 'i' to silence this warning}}335  int j = i ? : 1; // expected-warning {{variable 'i' is uninitialized when used here}}336}337 338void *test47(int *i)339{340  return i ? : 0; // no-warning341}342 343void *test49(int *i)344{345  int a;346  return &a ? : i; // no-warning347}348 349void test50(void)350{351  char c[1 ? : 2]; // no-warning352}353 354int test51(void)355{356    __block int a;357    ^(void) {358      a = 42;359    }();360    return a; // no-warning361}362 363// FIXME: This is a false positive, but it tests logical operations in switch statements.364int test52(int a, int b) {365  int x;  // expected-note {{initialize the variable 'x' to silence this warning}}366  switch (a || b) { // expected-warning {{switch condition has boolean value}}367    case 0:368      x = 1;369      break;370    case 1:371      x = 2;372      break;373  }374  return x; // expected-warning {{variable 'x' may be uninitialized when used here}}375}376 377void test53(void) {378  int x; // expected-note {{initialize the variable 'x' to silence this warning}}379  int y = (x);  // expected-warning {{variable 'x' is uninitialized when used here}}380}381 382// This CFG caused the uninitialized values warning to inf-loop.383extern int PR10379_g(void);384void PR10379_f(int *len) {385  int new_len; // expected-note{{initialize the variable 'new_len' to silence this warning}}386  for (int i = 0; i < 42 && PR10379_g() == 0; i++) {387    if (PR10379_g() == 1)388      continue;389    if (PR10379_g() == 2)390      PR10379_f(&new_len);391    else if (PR10379_g() == 3)392      PR10379_f(&new_len);393    *len += new_len; // expected-warning {{variable 'new_len' may be uninitialized when used here}}394  }395}396 397// Test that sizeof(VLA) doesn't trigger a warning.398void test_vla_sizeof(int x) {399  double (*memory)[2][x] = malloc(sizeof(*memory)); // no-warning400}401 402// Test absurd case of deadcode + use of blocks.  This previously was a false positive403// due to an analysis bug.404int test_block_and_dead_code(void) {405  __block int x;406  ^{ x = 1; }();407  if (0)408    return x;409  return x; // no-warning410}411 412// This previously triggered an infinite loop in the analysis.413void PR11069(int a, int b) {414  unsigned long flags;415  for (;;) {416    if (a && !b)417      break;418  }419  for (;;) {420    // This does not trigger a warning because it isn't a real use.421    (void)(flags); // no-warning422  }423}424 425// Test uninitialized value used in loop condition.426void rdar9432305(float *P) {427  int i; // expected-note {{initialize the variable 'i' to silence this warning}}428  for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}}429    P[i] = 0.0f;430}431 432// Test that fixits are not emitted inside macros.433#define UNINIT(T, x, y) T x; T y = x;434#define ASSIGN(T, x, y) T y = x;435void test54(void) {436  UNINIT(int, a, b);  // expected-warning {{variable 'a' is uninitialized when used here}} \437                      // expected-note {{variable 'a' is declared here}}438  int c;  // expected-note {{initialize the variable 'c' to silence this warning}}439  ASSIGN(int, c, d);  // expected-warning {{variable 'c' is uninitialized when used here}}440}441 442// Taking the address is fine443struct { struct { void *p; } a; } test55 = { { &test55.a }}; // no-warning444struct { struct { void *p; } a; } test56 = { { &(test56.a) }}; // no-warning445 446void uninit_in_loop(void) {447  int produce(void);448  void consume(int);449  for (int n = 0; n < 100; ++n) {450    int k; // expected-note {{initialize}}451    consume(k); // expected-warning {{variable 'k' is uninitialized}}452    k = produce();453  }454}455 456void uninit_in_loop_goto(void) {457  int produce(void);458  void consume(int);459  for (int n = 0; n < 100; ++n) {460    goto skip_decl;461    int k; // expected-note {{initialize}}462skip_decl:463    // FIXME: This should produce the 'is uninitialized' diagnostic, but we464    // don't have enough information in the CFG to easily tell that the465    // variable's scope has been left and re-entered.466    consume(k); // expected-warning {{variable 'k' may be uninitialized}}467    k = produce();468  }469}470 471typedef char jmp_buf[256];472extern int setjmp(jmp_buf env); // implicitly returns_twice473 474void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn));475 476int returns_twice(void) {477  int a; // expected-note {{initialize}}478  if (!a) { // expected-warning {{variable 'a' is uninitialized}}479    jmp_buf env;480    int b;481    if (setjmp(env) == 0) {482      do_stuff_and_longjmp(env, &b);483    } else {484      a = b; // no warning485    }486  }487  return a;488}489 490int compound_assign(int *arr, int n) {491  int sum; // expected-note {{initialize}}492  for (int i = 0; i < n; ++i)493    sum += arr[i]; // expected-warning {{variable 'sum' is uninitialized}}494  return sum / n;495}496 497int compound_assign_2(void) {498  int x; // expected-note {{initialize}}499  return x += 1; // expected-warning {{variable 'x' is uninitialized}}500}501 502int compound_assign_3(void) {503  int x; // expected-note {{initialize}}504  x *= 0; // expected-warning {{variable 'x' is uninitialized}}505  return x;506}507 508int self_init_in_cond(int *p) {509  int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok510  return n;511}512 513void test_analyzer_noreturn_aux(void) __attribute__((analyzer_noreturn));514 515void test_analyzer_noreturn(int y) {516  int x; // expected-note {{initialize the variable 'x' to silence this warning}}517  if (y) {518    test_analyzer_noreturn_aux();519	++x; // no-warning520  }521  else {522	++x; // expected-warning {{variable 'x' is uninitialized when used here}}523  }524}525void test_analyzer_noreturn_2(int y) {526  int x;527  if (y) {528    test_analyzer_noreturn_aux();529  }530  else {531	x = 1;532  }533  ++x; // no-warning534}535 536// Do not diagnose (functionally) empty structures as being uninitalized537// variables; see GH26842538struct empty {};539struct full_of_empty {540  int : 0;541  int : 12;542  struct empty e;543};544 545struct empty empty_test_1(void) {546  struct empty e;547  return e; // no-warning548}549 550struct full_of_empty empty_test_2(void) {551  struct full_of_empty e;552  return e; // no-warning553}554 555struct with_explicit_field {556  int x;557  int y [[clang::require_explicit_initialization]]; // #FIELD_Y558};559 560struct with_explicit_array {561  [[clang::require_explicit_initialization]] int arr[2]; // #FIELD_ARR562};563 564struct with_explicit_flex_array {565  int x;566  [[clang::require_explicit_initialization]] int flex_arr[]; // #FIELD_FLEX_ARR567};568 569void aggregate() {570  struct with_explicit_field a; // expected-warning {{field in 'with_explicit_field' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_Y {{'y' declared here}}571  struct with_explicit_field b = {1}; // expected-warning {{field 'y' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_Y {{'y' declared here}}572  (void)(&a != &b);573 574  struct with_explicit_field c = {1, 2};575  struct with_explicit_field d = {.y = 3};576  (void)(&c != &d);577 578  struct with_explicit_array e = {{1}};  // OK -- part of array is still initialized579  (void)e;580 581  struct with_explicit_flex_array f = {2}; // expected-warning {{field 'flex_arr' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_FLEX_ARR {{'flex_arr' declared here}}582  (void)f;583 584  (void)sizeof({ struct with_explicit_field a; a; });  // no warning -- unevaluated operand585}586