1 // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1 2 3 // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1 4 5 // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %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 *x_ptr; Base(int * y_ptr)13 Base(int *y_ptr) { 14 // store value of subclass member 15 x_ptr = y_ptr; 16 } 17 virtual ~Base(); 18 }; 19 20 class Derived : public Base { 21 public: 22 int y; Derived()23 Derived():Base(&y) { 24 y = 10; 25 } 26 ~Derived(); 27 }; 28 ~Base()29Base::~Base() { 30 // ok access its own member 31 assert(__msan_test_shadow(&this->x_ptr, sizeof(this->x_ptr)) == -1); 32 // bad access subclass member 33 assert(__msan_test_shadow(this->x_ptr, sizeof(*this->x_ptr)) != -1); 34 } 35 ~Derived()36Derived::~Derived() { 37 // ok to access its own members 38 assert(__msan_test_shadow(&this->y, sizeof(this->y)) == -1); 39 // ok access base class members 40 assert(__msan_test_shadow(&this->x_ptr, sizeof(this->x_ptr)) == -1); 41 } 42 main()43int main() { 44 Derived *d = new Derived(); 45 assert(__msan_test_shadow(&d->x_ptr, sizeof(d->x_ptr)) == -1); 46 d->~Derived(); 47 assert(__msan_test_shadow(&d->x_ptr, sizeof(d->x_ptr)) != -1); 48 return 0; 49 } 50