11dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
21dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
31dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Roseextern void clang_analyzer_eval(bool);
41dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Roseextern "C" char *strdup(const char *s);
5786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose
6786e6204e55cc01094a3e86104c82932a65fb2caJordan Rosenamespace PR14054_reduced {
7786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  struct Definition;
8786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  struct ParseNode {
9786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    union {
10786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose      Definition *lexdef;
11786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose      ParseNode *data;
12786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    } pn_u;
13786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  };
14786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  struct Definition : public ParseNode { };
15786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose
16786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  void CloneParseTree(ParseNode *opn, ParseNode *pn,  ParseNode *x) {
17786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // This used to cause an assertion failure because:
18786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // 1. The implicit operator= for unions assigns all members of the union,
19786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    //    not just the active one (b/c there's no way to know which is active).
20786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // 2. RegionStore dutifully stored all the variants at the same offset;
21786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    //    the last one won.
22786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // 3. We asked for the value of the first variant but got back a conjured
23786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    //    symbol for the second variant.
24786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // 4. We ended up trying to add a base cast to a region of the wrong type.
25786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    //
26786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // Now (at the time this test was added), we instead treat all variants of
27786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    // a union as different offsets, but only allow one to be active at a time.
28786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    *pn = *opn;
29786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    x = pn->pn_u.lexdef->pn_u.lexdef;
30786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  }
31786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose}
32786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose
33786e6204e55cc01094a3e86104c82932a65fb2caJordan Rosenamespace PR14054_original {
34786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  struct Definition;
35786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  struct ParseNode {
36786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    union {
37786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose      struct {
38786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose        union {};
39786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose        Definition *lexdef;
40786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose      } name;
41786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose      class {
42786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose        int *target;
43786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose        ParseNode *data;
44786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose      } xmlpi;
45786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    } pn_u;
46786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  };
47786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  struct Definition : public ParseNode { };
48786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose
49786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  void CloneParseTree(ParseNode *opn, ParseNode *pn,  ParseNode *x) {
50786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    pn->pn_u = opn->pn_u;
51786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose    x = pn->pn_u.name.lexdef->pn_u.name.lexdef;
52786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose  }
53786e6204e55cc01094a3e86104c82932a65fb2caJordan Rose}
541dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
551dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rosenamespace PR17596 {
561dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  union IntOrString {
571dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    int i;
581dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    char *s;
591dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  };
601dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
611dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  extern void process(IntOrString);
621dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
631dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  void test() {
641dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString uu;
651dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu.s = strdup("");
661dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    process(uu);
671dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  }
681dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
691dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  void testPositive() {
701dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString uu;
711dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu.s = strdup("");
721dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  } // expected-warning{{leak}}
731dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
741dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  void testCopy() {
751dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString uu;
761dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu.i = 4;
771dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    clang_analyzer_eval(uu.i == 4); // expected-warning{{TRUE}}
781dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
791dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString vv;
801dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    vv.i = 5;
811dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu = vv;
821dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    // FIXME: Should be true.
831dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    clang_analyzer_eval(uu.i == 5); // expected-warning{{UNKNOWN}}
841dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  }
851dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
861dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  void testInvalidation() {
871dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString uu;
881dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu.s = strdup("");
891dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
901dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString vv;
911dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    char str[] = "abc";
921dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    vv.s = str;
931dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
941dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    // FIXME: This is a leak of uu.s.
951dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu = vv;
961dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  }
971dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
981dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  void testIndirectInvalidation() {
991dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    IntOrString uu;
1001dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    char str[] = "abc";
1011dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    uu.s = str;
1021dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
1031dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{TRUE}}
1041dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose
1051dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    process(uu);
1061dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose    clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{UNKNOWN}}
1071dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose  }
1081dc31f5ead63d7197edf6f34a7821b93ea6698a1Jordan Rose}
109