Home | History | Annotate | Download | only in msan
      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;
     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;
     23   Derived():Base(&y) {
     24     y = 10;
     25   }
     26   ~Derived();
     27 };
     28 
     29 Base::~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 
     36 Derived::~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 
     43 int 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