blob: 2bffe78b41c25b12745443629e363e0e661767a2 [file] [log] [blame]
Jordan Rose786e6202012-10-10 23:23:21 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core %s -verify
Andy Gibbs8e8fb3b2012-10-19 12:44:48 +00002// expected-no-diagnostics
Jordan Rose786e6202012-10-10 23:23:21 +00003
4namespace 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
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
31namespace 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
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}