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