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 Song int 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