derived-to-base.cpp revision bfa9ab8183e2fdc74f8633d758cb0c6201314320
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s 2 3void clang_analyzer_eval(bool); 4 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} 18 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}; 27 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} 88 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} 138