Index: test/msan/dtor-base-access.cc =================================================================== --- /dev/null +++ test/msan/dtor-base-access.cc @@ -0,0 +1,55 @@ +// 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 + +// 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 + +// 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 + +// XFAIL: * + +#include +#include + +class Base { + public: + int x; + Base(int *y_ptr) { + // store value of subclass member + x = *y_ptr; + } + ~Base(); +}; + +class Derived : Base { + public: + int y; + Derived():Base(&y) { + y = 10; + } + ~Derived(); +}; + +// retrieve address of subclass member +static int *addr(Base *b) { + return &b->x; +} + +Base::~Base() { + // ok access its own member + assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1); + // bad access subclass member: trivial + assert(__msan_test_shadow(addr(this), sizeof(*addr(this))) != -1); +} + +Derived::~Derived() { + // ok to access its own members + assert(__msan_test_shadow(&this->y, sizeof(this->y)) == -1); + // ok access base class members + assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1); +} + +int main() { + Derived *d = new Derived(); + d->~Derived(); + assert(__msan_test_shadow(d, sizeof(*d)) != -1); + return 0; +}