1*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 2*7c3d14c8STreehugger Robot 3*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 4*7c3d14c8STreehugger Robot 5*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 6*7c3d14c8STreehugger Robot 7*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -DCVPTR=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t 8*7c3d14c8STreehugger Robot 9*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -DEAVPTR=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t 10*7c3d14c8STreehugger Robot 11*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -DEDVPTR=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t 12*7c3d14c8STreehugger Robot 13*7c3d14c8STreehugger Robot // Expected to quit due to invalid access when invoking 14*7c3d14c8STreehugger Robot // function using vtable. 15*7c3d14c8STreehugger Robot 16*7c3d14c8STreehugger Robot class A { 17*7c3d14c8STreehugger Robot public: 18*7c3d14c8STreehugger Robot int x; ~A()19*7c3d14c8STreehugger Robot virtual ~A() { 20*7c3d14c8STreehugger Robot // Should succeed 21*7c3d14c8STreehugger Robot this->A_Foo(); 22*7c3d14c8STreehugger Robot } A_Foo()23*7c3d14c8STreehugger Robot virtual void A_Foo() {} 24*7c3d14c8STreehugger Robot }; 25*7c3d14c8STreehugger Robot 26*7c3d14c8STreehugger Robot class B : public virtual A { 27*7c3d14c8STreehugger Robot public: 28*7c3d14c8STreehugger Robot int y; ~B()29*7c3d14c8STreehugger Robot virtual ~B() {} A_Foo()30*7c3d14c8STreehugger Robot virtual void A_Foo() {} 31*7c3d14c8STreehugger Robot }; 32*7c3d14c8STreehugger Robot 33*7c3d14c8STreehugger Robot class C : public B { 34*7c3d14c8STreehugger Robot public: 35*7c3d14c8STreehugger Robot int z; ~C()36*7c3d14c8STreehugger Robot ~C() {} 37*7c3d14c8STreehugger Robot }; 38*7c3d14c8STreehugger Robot 39*7c3d14c8STreehugger Robot class D { 40*7c3d14c8STreehugger Robot public: 41*7c3d14c8STreehugger Robot int w; ~D()42*7c3d14c8STreehugger Robot ~D() {} D_Foo()43*7c3d14c8STreehugger Robot virtual void D_Foo() {} 44*7c3d14c8STreehugger Robot }; 45*7c3d14c8STreehugger Robot 46*7c3d14c8STreehugger Robot class E : public virtual A, public virtual D { 47*7c3d14c8STreehugger Robot public: 48*7c3d14c8STreehugger Robot int u; ~E()49*7c3d14c8STreehugger Robot ~E() {} A_Foo()50*7c3d14c8STreehugger Robot void A_Foo() {} 51*7c3d14c8STreehugger Robot }; 52*7c3d14c8STreehugger Robot main()53*7c3d14c8STreehugger Robotint main() { 54*7c3d14c8STreehugger Robot // Simple linear inheritance 55*7c3d14c8STreehugger Robot C *c = new C(); 56*7c3d14c8STreehugger Robot c->~C(); 57*7c3d14c8STreehugger Robot // This fails 58*7c3d14c8STreehugger Robot #ifdef CVPTR 59*7c3d14c8STreehugger Robot c->A_Foo(); 60*7c3d14c8STreehugger Robot #endif 61*7c3d14c8STreehugger Robot 62*7c3d14c8STreehugger Robot // Multiple inheritance, so has multiple vtables 63*7c3d14c8STreehugger Robot E *e = new E(); 64*7c3d14c8STreehugger Robot e->~E(); 65*7c3d14c8STreehugger Robot // Both of these fail 66*7c3d14c8STreehugger Robot #ifdef EAVPTR 67*7c3d14c8STreehugger Robot e->A_Foo(); 68*7c3d14c8STreehugger Robot #endif 69*7c3d14c8STreehugger Robot #ifdef EDVPTR 70*7c3d14c8STreehugger Robot e->D_Foo(); 71*7c3d14c8STreehugger Robot #endif 72*7c3d14c8STreehugger Robot } 73