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