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