Index: test/msan/dtor-multiple-inheritance.cc =================================================================== --- test/msan/dtor-multiple-inheritance.cc +++ test/msan/dtor-multiple-inheritance.cc @@ -14,24 +14,23 @@ #include #include + +int *temp_x; +int *temp_y; +int *temp_z; +int *temp_w; + class A { public: int x; - int *y_ptr; - int *z_ptr; - int *w_ptr; A() { x = 5; } - void set_ptrs(int *y_ptr, int *z_ptr, int *w_ptr) { - this->y_ptr = y_ptr; - this->z_ptr = z_ptr; - this->w_ptr = w_ptr; - } virtual ~A() { assert(__msan_test_shadow(&this->x, sizeof(this->x) == -1)); + assert(__msan_test_shadow(temp_x, sizeof(*temp_x)) == -1); // bad access subclass member - assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) != -1); - assert(__msan_test_shadow(this->z_ptr, sizeof(*this->z_ptr)) != -1); - assert(__msan_test_shadow(this->w_ptr, sizeof(*this->w_ptr)) != -1); + assert(__msan_test_shadow(temp_y, sizeof(*temp_y)) != -1); + assert(__msan_test_shadow(temp_z, sizeof(*temp_z)) != -1); + assert(__msan_test_shadow(temp_w, sizeof(*temp_w)) != -1); } }; @@ -42,11 +41,11 @@ virtual ~B() { assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1); assert(__msan_test_shadow(&this->y, sizeof(this->y)) == -1); - assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) == -1); - - // memory in subclasses is poisoned - assert(__msan_test_shadow(this->z_ptr, sizeof(*this->z_ptr)) != -1); - assert(__msan_test_shadow(this->w_ptr, sizeof(*this->w_ptr)) != -1); + assert(__msan_test_shadow(temp_x, sizeof(*temp_x)) == -1); + assert(__msan_test_shadow(temp_y, sizeof(*temp_y)) == -1); + // Memory in subclasses is poisoned. + assert(__msan_test_shadow(temp_z, sizeof(*temp_z)) != -1); + assert(__msan_test_shadow(temp_w, sizeof(*temp_w)) != -1); } }; @@ -57,11 +56,11 @@ virtual ~C() { assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1); assert(__msan_test_shadow(&this->z, sizeof(this->z)) == -1); - assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) == -1); - assert(__msan_test_shadow(this->z_ptr, sizeof(*this->z_ptr) == -1)); - - // memory in subclasses is poisoned - assert(__msan_test_shadow(this->w_ptr, sizeof(*this->w_ptr)) != -1); + assert(__msan_test_shadow(temp_x, sizeof(*temp_x)) == -1); + assert(__msan_test_shadow(temp_y, sizeof(*temp_y)) == -1); + assert(__msan_test_shadow(temp_z, sizeof(*temp_z)) == -1); + // Memory in subclasses is poisoned. + assert(__msan_test_shadow(temp_w, sizeof(*temp_w)) != -1); } }; @@ -72,25 +71,35 @@ ~Derived() { assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1); assert(__msan_test_shadow(&this->y, sizeof(this->y)) == -1); + assert(__msan_test_shadow(&this->z, sizeof(this->z)) == -1); assert(__msan_test_shadow(&this->w, sizeof(this->w)) == -1); + assert(__msan_test_shadow(temp_x, sizeof(*temp_x)) == -1); + assert(__msan_test_shadow(temp_y, sizeof(*temp_y)) == -1); + assert(__msan_test_shadow(temp_z, sizeof(*temp_z)) == -1); + assert(__msan_test_shadow(temp_w, sizeof(*temp_w)) == -1); } }; + int main() { Derived *d = new Derived(); - d->set_ptrs(&d->y, &d->z, &d->w); + + // Keep track of members inherited from virtual bases, + // since the virtual base table is inaccessible after destruction. + temp_x = &d->x; + temp_y = &d->y; + temp_z = &d->z; + temp_w = &d->w; // Order of destruction: Derived, C, B, A d->~Derived(); // Verify that local pointer is unpoisoned, and that the object's // members are. assert(__msan_test_shadow(&d, sizeof(d)) == -1); - assert(__msan_test_shadow(&d->x, sizeof(d->x)) != -1); - assert(__msan_test_shadow(&d->y, sizeof(d->y)) != -1); - assert(__msan_test_shadow(&d->z, sizeof(d->z)) != -1); assert(__msan_test_shadow(&d->w, sizeof(d->w)) != -1); - assert(__msan_test_shadow(&d->y_ptr, sizeof(d->y_ptr)) != -1); - assert(__msan_test_shadow(&d->z_ptr, sizeof(d->z_ptr)) != -1); - assert(__msan_test_shadow(&d->w_ptr, sizeof(d->w_ptr)) != -1); + assert(__msan_test_shadow(temp_x, sizeof(*temp_x)) != -1); + assert(__msan_test_shadow(temp_y, sizeof(*temp_y)) != -1); + assert(__msan_test_shadow(temp_z, sizeof(*temp_z)) != -1); + assert(__msan_test_shadow(temp_w, sizeof(*temp_w)) != -1); return 0; } Index: test/msan/dtor-trivial.cpp =================================================================== --- test/msan/dtor-trivial.cpp +++ test/msan/dtor-trivial.cpp @@ -4,7 +4,9 @@ // 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 -// TODO Success pending on resolution of 596 +// TODO Success pending on resolution of +// https://github.com/google/sanitizers/issues/596 + // XFAIL: * #include Index: test/msan/dtor-vtable.cc =================================================================== --- /dev/null +++ test/msan/dtor-vtable.cc @@ -0,0 +1,26 @@ +// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t + +// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t + +// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t + +// Expected to quit due to invalid access when invoking +// function using vtable. +// XFAIL: * + +#include + +class A { +public: + int x; + ~A() {} + virtual void A_Foo() {} +}; + +int main() { + A *a = new A(); + a->~A(); + // Shouldn't be allowed to invoke function via vtable. + a->A_Foo(); + return 0; +}