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