derived-to-base.cpp revision b11a3ada9a22e146c6edd33bcc6301e221fedd7a
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -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