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; 13 Base() { b = 1; } 14 ~Base(); 15 }; 16 17 class TrivialBaseBefore { 18 public: 19 int tb0; 20 TrivialBaseBefore() { tb0 = 1; } 21 }; 22 23 class TrivialBaseAfter { 24 public: 25 int tb1; 26 TrivialBaseAfter() { tb1 = 1; } 27 }; 28 29 class Derived : public TrivialBaseBefore, public Base, public TrivialBaseAfter { 30 public: 31 int d; 32 Derived() { d = 1; } 33 ~Derived(); 34 }; 35 36 Derived *g; 37 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 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 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