1ee04959f88e26ed38dccf4aed2ff10cad1f703c9Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
2b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
3b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rosevoid clang_analyzer_eval(bool);
44fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu
54fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xuclass A {
64fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xuprotected:
74fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu  int x;
84fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu};
94fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu
104fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xuclass B : public A {
114fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xupublic:
124fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu  void f();
134fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu};
144fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu
154fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xuvoid B::f() {
164fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu  x = 3;
174fd56816e0925c04f2c92e75399f5c9018d5d6fbZhongxing Xu}
182c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose
192c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose
202c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Roseclass C : public B {
212c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rosepublic:
222c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  void g() {
232c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose    // This used to crash because we are upcasting through two bases.
242c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose    x = 5;
252c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  }
262c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose};
27b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
28b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
29b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rosenamespace VirtualBaseClasses {
30b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class A {
31b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  protected:
32b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    int x;
33b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  };
34b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
35b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class B : public virtual A {
36b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  public:
37b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    int getX() { return x; }
38b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  };
39b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
40b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class C : public virtual A {
41b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  public:
42b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    void setX() { x = 42; }
43b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  };
44b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
45b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class D : public B, public C {};
46b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class DV : virtual public B, public C {};
47b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class DV2 : public B, virtual public C {};
48b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
49b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  void test() {
50b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    D d;
51b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    d.setX();
52b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
53b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
54b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    DV dv;
55b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    dv.setX();
56b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
57b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
58b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    DV2 dv2;
59b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    dv2.setX();
60b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
61b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  }
62b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
63b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
64b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  // Make sure we're consistent about the offset of the A subobject within an
65b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  // Intermediate virtual base class.
66b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class Padding1 { int unused; };
67b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class Padding2 { int unused; };
68b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class Intermediate : public Padding1, public A, public Padding2 {};
69b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
70b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class BI : public virtual Intermediate {
71b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  public:
72b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    int getX() { return x; }
73b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  };
74b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
75b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class CI : public virtual Intermediate {
76b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  public:
77b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    void setX() { x = 42; }
78b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  };
79b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
80b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  class DI : public BI, public CI {};
81b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose
82b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  void testIntermediate() {
83b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    DI d;
84b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    d.setX();
85b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose    clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
86b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose  }
87b11a3ada9a22e146c6edd33bcc6301e221fedd7aJordan Rose}
880a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
890a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
900a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rosenamespace DynamicVirtualUpcast {
910a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class A {
920a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  public:
930a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    virtual ~A();
940a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  };
950a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
960a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class B : virtual public A {};
970a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class C : virtual public B {};
980a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class D : virtual public C {};
990a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1000a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  bool testCast(A *a) {
1010a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);
1020a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  }
1030a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1040a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  void test() {
1050a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    D d;
1060a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
1070a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  }
1080a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose}
1090a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1100a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rosenamespace DynamicMultipleInheritanceUpcast {
1110a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class B {
1120a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  public:
1130a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    virtual ~B();
1140a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  };
1150a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class C {
1160a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  public:
1170a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    virtual ~C();
1180a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  };
1190a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class D : public B, public C {};
1200a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1210a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  bool testCast(B *a) {
1220a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    return dynamic_cast<C*>(a);
1230a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  }
1240a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1250a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  void test() {
1260a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    D d;
1270a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
1280a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  }
1290a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1300a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1310a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  class DV : virtual public B, virtual public C {};
1320a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose
1330a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  void testVirtual() {
1340a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    DV d;
1350a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
1360a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose  }
1370a5629812019ce8bef86ade5425ac261bb544fd8Jordan Rose}
138