unions.cpp revision 786e6204e55cc01094a3e86104c82932a65fb2ca
1// RUN: %clang_cc1 -analyze -analyzer-checker=core %s -verify
2
3namespace PR14054_reduced {
4  struct Definition;
5  struct ParseNode {
6    union {
7      Definition *lexdef;
8      ParseNode *data;
9    } pn_u;
10  };
11  struct Definition : public ParseNode { };
12
13  void CloneParseTree(ParseNode *opn, ParseNode *pn,  ParseNode *x) {
14    // This used to cause an assertion failure because:
15    // 1. The implicit operator= for unions assigns all members of the union,
16    //    not just the active one (b/c there's no way to know which is active).
17    // 2. RegionStore dutifully stored all the variants at the same offset;
18    //    the last one won.
19    // 3. We asked for the value of the first variant but got back a conjured
20    //    symbol for the second variant.
21    // 4. We ended up trying to add a base cast to a region of the wrong type.
22    //
23    // Now (at the time this test was added), we instead treat all variants of
24    // a union as different offsets, but only allow one to be active at a time.
25    *pn = *opn;
26    x = pn->pn_u.lexdef->pn_u.lexdef;
27  }
28}
29
30namespace PR14054_original {
31  struct Definition;
32  struct ParseNode {
33    union {
34      struct {
35        union {};
36        Definition *lexdef;
37      } name;
38      class {
39        int *target;
40        ParseNode *data;
41      } xmlpi;
42    } pn_u;
43  };
44  struct Definition : public ParseNode { };
45
46  void CloneParseTree(ParseNode *opn, ParseNode *pn,  ParseNode *x) {
47    pn->pn_u = opn->pn_u;
48    x = pn->pn_u.name.lexdef->pn_u.name.lexdef;
49  }
50}
51