1 | // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t |
2 | |
3 | // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t |
4 | |
5 | // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t |
6 | |
7 | // RUN: %clangxx_msan %s -DVPTRA=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && not %run %t |
8 | |
9 | // RUN: %clangxx_msan %s -DVPTRCA=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && not %run %t |
10 | |
11 | // RUN: %clangxx_msan %s -DVPTRCB=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && not %run %t |
12 | |
13 | // RUN: %clangxx_msan %s -DVPTRC=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && not %run %t |
14 | |
15 | // Expected to quit due to invalid access when invoking |
16 | // function using vtable. |
17 | |
18 | #include <sanitizer/msan_interface.h> |
19 | #include <stdio.h> |
20 | #include <assert.h> |
21 | |
22 | class A { |
23 | public: |
24 | int x; |
25 | ~A() {} |
26 | virtual void A_Foo() {} |
27 | }; |
28 | |
29 | class B { |
30 | public: |
31 | int y; |
32 | ~B() {} |
33 | virtual void B_Foo() {} |
34 | }; |
35 | |
36 | class C : public A, public B { |
37 | public: |
38 | int z; |
39 | ~C() {} |
40 | virtual void C_Foo() {} |
41 | }; |
42 | |
43 | int main() { |
44 | A *a = new A(); |
45 | a->~A(); |
46 | |
47 | // Shouldn't be allowed to invoke function via vtable. |
48 | #ifdef VPTRA |
49 | a->A_Foo(); |
50 | #endif |
51 | |
52 | C *c = new C(); |
53 | c->~C(); |
54 | |
55 | #ifdef VPTRCA |
56 | c->A_Foo(); |
57 | #endif |
58 | |
59 | #ifdef VPTRCB |
60 | c->B_Foo(); |
61 | #endif |
62 | |
63 | #ifdef VPTRC |
64 | c->C_Foo(); |
65 | #endif |
66 | |
67 | return 0; |
68 | } |
69 | |