blob: 57689d19e3b942a9858ec83029b97d37cc0ead88 [file] [log] [blame]
Anna Zaksbfa9ab82013-01-24 23:15:30 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
Jordan Roseb11a3ad2012-08-13 22:11:34 +00002
3void clang_analyzer_eval(bool);
Zhongxing Xu4fd56812010-11-26 08:21:53 +00004
5class A {
6protected:
7 int x;
8};
9
10class B : public A {
11public:
12 void f();
13};
14
15void B::f() {
16 x = 3;
17}
Jordan Rose2c5f8d72012-08-09 21:24:02 +000018
19
20class C : public B {
21public:
22 void g() {
23 // This used to crash because we are upcasting through two bases.
24 x = 5;
25 }
26};
Jordan Roseb11a3ad2012-08-13 22:11:34 +000027
28
29namespace VirtualBaseClasses {
30 class A {
31 protected:
32 int x;
33 };
34
35 class B : public virtual A {
36 public:
37 int getX() { return x; }
38 };
39
40 class C : public virtual A {
41 public:
42 void setX() { x = 42; }
43 };
44
45 class D : public B, public C {};
46 class DV : virtual public B, public C {};
47 class DV2 : public B, virtual public C {};
48
49 void test() {
50 D d;
51 d.setX();
52 clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
53
54 DV dv;
55 dv.setX();
56 clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
57
58 DV2 dv2;
59 dv2.setX();
60 clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
61 }
62
63
64 // Make sure we're consistent about the offset of the A subobject within an
65 // Intermediate virtual base class.
66 class Padding1 { int unused; };
67 class Padding2 { int unused; };
68 class Intermediate : public Padding1, public A, public Padding2 {};
69
70 class BI : public virtual Intermediate {
71 public:
72 int getX() { return x; }
73 };
74
75 class CI : public virtual Intermediate {
76 public:
77 void setX() { x = 42; }
78 };
79
80 class DI : public BI, public CI {};
81
82 void testIntermediate() {
83 DI d;
84 d.setX();
85 clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
86 }
87}
Jordan Rose0a562982012-08-13 22:11:42 +000088
89
90namespace DynamicVirtualUpcast {
91 class A {
92 public:
93 virtual ~A();
94 };
95
96 class B : virtual public A {};
97 class C : virtual public B {};
98 class D : virtual public C {};
99
100 bool testCast(A *a) {
101 return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);
102 }
103
104 void test() {
105 D d;
106 clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
107 }
108}
109
110namespace DynamicMultipleInheritanceUpcast {
111 class B {
112 public:
113 virtual ~B();
114 };
115 class C {
116 public:
117 virtual ~C();
118 };
119 class D : public B, public C {};
120
121 bool testCast(B *a) {
122 return dynamic_cast<C*>(a);
123 }
124
125 void test() {
126 D d;
127 clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
128 }
129
130
131 class DV : virtual public B, virtual public C {};
132
133 void testVirtual() {
134 DV d;
135 clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
136 }
137}