brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 76eb205 Raw
144 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -analyzer-config eagerly-assume=false -verify2 3extern void clang_analyzer_eval(bool);4extern void clang_analyzer_warnIfReached();5extern "C" char *strdup(const char *s);6 7namespace PR14054_reduced {8  struct Definition;9  struct ParseNode {10    union {11      Definition *lexdef;12      ParseNode *data;13    } pn_u;14  };15  struct Definition : public ParseNode { };16 17  void CloneParseTree(ParseNode *opn, ParseNode *pn,  ParseNode *x) {18    // This used to cause an assertion failure because:19    // 1. The implicit operator= for unions assigns all members of the union,20    //    not just the active one (b/c there's no way to know which is active).21    // 2. RegionStore dutifully stored all the variants at the same offset;22    //    the last one won.23    // 3. We asked for the value of the first variant but got back a conjured24    //    symbol for the second variant.25    // 4. We ended up trying to add a base cast to a region of the wrong type.26    //27    // Now (at the time this test was added), we instead treat all variants of28    // a union as different offsets, but only allow one to be active at a time.29    *pn = *opn;30    x = pn->pn_u.lexdef->pn_u.lexdef;31  }32}33 34namespace PR14054_original {35  struct Definition;36  struct ParseNode {37    union {38      struct {39        union {}; // expected-warning {{does not declare anything}}40        Definition *lexdef;41      } name;42      class {43        int *target;44        ParseNode *data;45      } xmlpi;46    } pn_u;47  };48  struct Definition : public ParseNode { };49 50  void CloneParseTree(ParseNode *opn, ParseNode *pn,  ParseNode *x) {51    pn->pn_u = opn->pn_u;52    x = pn->pn_u.name.lexdef->pn_u.name.lexdef;53  }54}55 56namespace PR17596 {57  union IntOrString {58    int i;59    char *s;60  };61 62  extern void process(IntOrString);63 64  void test() {65    IntOrString uu;66    uu.s = strdup("");67    process(uu);68  }69 70  void testPositive() {71    IntOrString uu;72    uu.s = strdup("");73  } // expected-warning{{leak}}74 75  void testCopy() {76    IntOrString uu;77    uu.i = 4;78    clang_analyzer_eval(uu.i == 4); // expected-warning{{TRUE}}79 80    IntOrString vv;81    vv.i = 5;82    uu = vv;83    clang_analyzer_eval(uu.i == 5); // expected-warning{{TRUE}}84  }85 86  void testInvalidation() {87    IntOrString uu;88    uu.s = strdup("");89 90    IntOrString vv;91    char str[] = "abc";92    vv.s = str;93 94    uu = vv;95  } // expected-warning{{leak}}96 97  void testIndirectInvalidation() {98    IntOrString uu;99    char str[] = "abc";100    uu.s = str;101 102    clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{TRUE}}103 104    process(uu);105    clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{UNKNOWN}}106  }107}108 109namespace assume_union_contents {110union U {111  int x;112};113 114U get();115 116void test() {117  U u = get();118  int y = 0;119  if (u.x)120    y = 1;121  if (u.x)122    y = 1 / y; // no-warning123}124} // end namespace assume_union_contents125 126namespace pr37688_deleted_union_destructor {127struct S { ~S(); };128struct A {129  ~A() noexcept {}130  union {131    struct {132      S s;133    } ss;134  };135};136void foo() {137  A a;138} // no-crash139void bar() {140  foo();141  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}142}143} // end namespace pr37688_deleted_union_destructor144