diff options
Diffstat (limited to 'test/msan/dtor-base-access.cc')
-rw-r--r-- | test/msan/dtor-base-access.cc | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/test/msan/dtor-base-access.cc b/test/msan/dtor-base-access.cc new file mode 100644 index 0000000000000..bed66fb621db0 --- /dev/null +++ b/test/msan/dtor-base-access.cc @@ -0,0 +1,49 @@ +// 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 + +#include <sanitizer/msan_interface.h> +#include <assert.h> + +class Base { + public: + int *x_ptr; + Base(int *y_ptr) { + // store value of subclass member + x_ptr = y_ptr; + } + virtual ~Base(); +}; + +class Derived : public Base { + public: + int y; + Derived():Base(&y) { + y = 10; + } + ~Derived(); +}; + +Base::~Base() { + // ok access its own member + assert(__msan_test_shadow(&this->x_ptr, sizeof(this->x_ptr)) == -1); + // bad access subclass member + assert(__msan_test_shadow(this->x_ptr, sizeof(*this->x_ptr)) != -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_ptr, sizeof(this->x_ptr)) == -1); +} + +int main() { + Derived *d = new Derived(); + assert(__msan_test_shadow(&d->x_ptr, sizeof(d->x_ptr)) == -1); + d->~Derived(); + assert(__msan_test_shadow(&d->x_ptr, sizeof(d->x_ptr)) != -1); + return 0; +} |