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