1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify 2 3 extern void clang_analyzer_eval(bool); 4 extern "C" char *strdup(const char *s); 5 mallocnull6namespace PR14054_reduced { 7 struct Definition; 8 struct ParseNode { 9 union { 10 Definition *lexdef; 11 ParseNode *data; 12 } pn_u; 13 }; 14 struct Definition : public ParseNode { }; 15 16 void CloneParseTree(ParseNode *opn, ParseNode *pn, ParseNode *x) { 17 // This used to cause an assertion failure because: 18 // 1. The implicit operator= for unions assigns all members of the union, 19 // not just the active one (b/c there's no way to know which is active). 20 // 2. RegionStore dutifully stored all the variants at the same offset; 21 // the last one won. 22 // 3. We asked for the value of the first variant but got back a conjured 23 // symbol for the second variant. 24 // 4. We ended up trying to add a base cast to a region of the wrong type. 25 // 26 // Now (at the time this test was added), we instead treat all variants of 27 // a union as different offsets, but only allow one to be active at a time. 28 *pn = *opn; 29 x = pn->pn_u.lexdef->pn_u.lexdef; 30 } 31 } 32 33 namespace PR14054_original { 34 struct Definition; 35 struct ParseNode { test_PR10163null36 union { 37 struct { 38 union {}; 39 Definition *lexdef; 40 } name; 41 class { 42 int *target; 43 ParseNode *data; 44 } xmlpi; 45 } pn_u; 46 }; 47 struct Definition : public ParseNode { }; 48 49 void CloneParseTree(ParseNode *opn, ParseNode *pn, ParseNode *x) { 50 pn->pn_u = opn->pn_u; 51 x = pn->pn_u.name.lexdef->pn_u.name.lexdef; 52 } makePointnull53} 54 55 namespace PR17596 { 56 union IntOrString { 57 int i; 58 char *s; 59 }; 60 61 extern void process(IntOrString); 62 63 void test() { 64 IntOrString uu; 65 uu.s = strdup(""); 66 process(uu); 67 } 68 69 void testPositive() { 70 IntOrString uu; 71 uu.s = strdup(""); 72 } // expected-warning{{leak}} 73 74 void testCopy() { 75 IntOrString uu; 76 uu.i = 4; 77 clang_analyzer_eval(uu.i == 4); // expected-warning{{TRUE}} 78 79 IntOrString vv; 80 vv.i = 5; 81 uu = vv; 82 clang_analyzer_eval(uu.i == 5); // expected-warning{{TRUE}} 83 } 84 85 void testInvalidation() { 86 IntOrString uu; 87 uu.s = strdup(""); 88 89 IntOrString vv; 90 char str[] = "abc"; 91 vv.s = str; 92 93 // FIXME: This is a leak of uu.s. 94 uu = vv; 95 } 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 109 namespace assume_union_contents { 110 union U { 111 int x; 112 }; 113 114 U get(); 115 116 void 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-warning 123 } 124 } // end namespace assume_union_contents 125