1 // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&1
2
3 // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&1
4
5 // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&1
6
7 #include <sanitizer/msan_interface.h>
8 #include <assert.h>
9
10 class Base {
11 public:
12 int b;
Base()13 Base() { b = 1; }
14 ~Base();
15 };
16
17 class TrivialBaseBefore {
18 public:
19 int tb0;
TrivialBaseBefore()20 TrivialBaseBefore() { tb0 = 1; }
21 };
22
23 class TrivialBaseAfter {
24 public:
25 int tb1;
TrivialBaseAfter()26 TrivialBaseAfter() { tb1 = 1; }
27 };
28
29 class Derived : public TrivialBaseBefore, public Base, public TrivialBaseAfter {
30 public:
31 int d;
Derived()32 Derived() { d = 1; }
33 ~Derived();
34 };
35
36 Derived *g;
37
~Base()38 Base::~Base() {
39 // ok to access its own members and earlier bases
40 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);
41 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);
42 // not ok to access others
43 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == 0);
44 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);
45 }
46
~Derived()47 Derived::~Derived() {
48 // ok to access everything
49 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);
50 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);
51 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == -1);
52 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == -1);
53 }
54
main()55 int main() {
56 g = new Derived();
57 // ok to access everything
58 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);
59 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);
60 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == -1);
61 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == -1);
62
63 g->~Derived();
64 // not ok to access everything
65 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == 0);
66 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == 0);
67 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == 0);
68 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);
69 return 0;
70 }
71