1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s
4 void clang_analyzer_eval(bool);
5 void clang_analyzer_checkInlined(bool);
25 // This used to crash because we are upcasting through two bases.
31 namespace VirtualBaseClasses {
37 class B : public virtual A {
39 int getX() { return x; }
42 class C : public virtual A {
44 void setX() { x = 42; }
47 class D : public B, public C {};
48 class DV : virtual public B, public C {};
49 class DV2 : public B, virtual public C {};
54 clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
58 clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
62 clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
66 // Make sure we're consistent about the offset of the A subobject within an
67 // Intermediate virtual base class.
68 class Padding1 { int unused; };
69 class Padding2 { int unused; };
70 class Intermediate : public Padding1, public A, public Padding2 {};
72 class BI : public virtual Intermediate {
74 int getX() { return x; }
77 class CI : public virtual Intermediate {
79 void setX() { x = 42; }
82 class DI : public BI, public CI {};
84 void testIntermediate() {
87 clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
92 namespace DynamicVirtualUpcast {
98 class B : virtual public A {};
99 class C : virtual public B {};
100 class D : virtual public C {};
102 bool testCast(A *a) {
103 return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);
108 clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
112 namespace DynamicMultipleInheritanceUpcast {
121 class D : public B, public C {};
123 bool testCast(B *a) {
124 return dynamic_cast<C*>(a);
129 clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
133 class DV : virtual public B, virtual public C {};
137 clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
141 namespace LazyBindings {
146 struct Derived : public Base {
150 struct DoubleDerived : public Derived {
154 int getX(const Base &obj) {
158 int getY(const Derived &obj) {
166 clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}
167 clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}
170 clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}
173 clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}
174 clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}
177 void testDoubleDerived() {
181 clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}
182 clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}
185 clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}
188 clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}
189 clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}
192 clang_analyzer_eval(getX(d3) == 1); // expected-warning{{TRUE}}
193 clang_analyzer_eval(getY(d3) == 2); // expected-warning{{TRUE}}
196 namespace WithOffset {
201 struct OffsetDerived : private Offset, public Base {
205 struct DoubleOffsetDerived : public OffsetDerived {
209 int getY(const OffsetDerived &obj) {
217 clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}
218 clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}
221 clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}
224 clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}
225 clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}
228 void testDoubleDerived() {
229 DoubleOffsetDerived d;
232 clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}
233 clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}
236 clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}
239 clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}
240 clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}
242 DoubleOffsetDerived d3(d);
243 clang_analyzer_eval(getX(d3) == 1); // expected-warning{{TRUE}}
244 clang_analyzer_eval(getY(d3) == 2); // expected-warning{{TRUE}}
248 namespace WithVTable {
249 struct DerivedVTBL : public Base {
251 virtual void method();
254 struct DoubleDerivedVTBL : public DerivedVTBL {
258 int getY(const DerivedVTBL &obj) {
262 int getZ(const DoubleDerivedVTBL &obj) {
270 clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}
271 clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}
274 clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}
278 clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}
279 clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}
284 void testDoubleDerived() {
289 clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}
290 clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}
291 clang_analyzer_eval(getZ(d) == 3); // expected-warning{{TRUE}}
294 clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}
297 clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}
298 clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}
300 DoubleDerivedVTBL d3(d);
301 clang_analyzer_eval(getX(d3) == 1); // expected-warning{{TRUE}}
302 clang_analyzer_eval(getY(d3) == 2); // expected-warning{{TRUE}}
303 clang_analyzer_eval(getZ(d3) == 3); // expected-warning{{TRUE}}
310 struct NonTrivialCopy {
313 NonTrivialCopy(const NonTrivialCopy &) {}
316 struct FullyDerived : private NonTrivialCopy, public Derived {
324 Wrapper(const FullyDerived &d) : d(d), zz(0) {}
328 Wrapper w((FullyDerived()));
332 clang_analyzer_eval(getX(w2.d) == 1); // expected-warning{{TRUE}}
338 namespace Redeclaration {
344 int get() { return value; }
349 class Derived : public Base {
354 void test(Derived d) {
355 d.foo(); // don't crash
356 d.bar(); // sanity check
359 b.foo(); // don't crash
361 d.value = 42; // don't crash
362 clang_analyzer_eval(d.get() == 42); // expected-warning{{TRUE}}
363 clang_analyzer_eval(b.get() == 42); // expected-warning{{TRUE}}
375 class Derived1 : public Base {
380 class Derived2 : public Derived1 {
383 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
389 Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2);
392 clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}
396 namespace VirtualInDerived {
402 class Derived1 : public Base {
408 class Derived2 : public Derived1 {
411 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
417 Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2);
420 clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}
430 class Derived1 : public Base {
436 class Derived2 : public Derived1 {
439 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
445 Derived1 *d1p = new Derived2;
448 clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}