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;
~A()19 virtual ~A() {
20 // Should succeed
21 this->A_Foo();
22 }
A_Foo()23 virtual void A_Foo() {}
24 };
25
26 class B : public virtual A {
27 public:
28 int y;
~B()29 virtual ~B() {}
A_Foo()30 virtual void A_Foo() {}
31 };
32
33 class C : public B {
34 public:
35 int z;
~C()36 ~C() {}
37 };
38
39 class D {
40 public:
41 int w;
~D()42 ~D() {}
D_Foo()43 virtual void D_Foo() {}
44 };
45
46 class E : public virtual A, public virtual D {
47 public:
48 int u;
~E()49 ~E() {}
A_Foo()50 void A_Foo() {}
51 };
52
main()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