Index: test/msan/dtor-multiple-inheritance.cc =================================================================== --- test/msan/dtor-multiple-inheritance.cc +++ test/msan/dtor-multiple-inheritance.cc @@ -13,6 +13,7 @@ #include #include +#include class A { public: @@ -27,6 +28,7 @@ this->w_ptr = w_ptr; } virtual ~A() { + printf("~A\n"); assert(__msan_test_shadow(&this->x, sizeof(this->x) == -1)); // bad access subclass member assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) != -1); @@ -40,6 +42,7 @@ int y; B() { y = 10; } virtual ~B() { + printf("~B\n"); 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); @@ -55,6 +58,7 @@ int z; C() { z = 15; } virtual ~C() { + printf("~C\n"); 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); @@ -70,6 +74,7 @@ int w; Derived() { w = 10; } ~Derived() { + printf("~D\n"); 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->w, sizeof(this->w)) == -1); @@ -80,17 +85,26 @@ Derived *d = new Derived(); d->set_ptrs(&d->y, &d->z, &d->w); + // Keep track of members inherited from virtual bases, + // since the virtula base table is inaccessible after destruction. + int *temp_x = &d->x; + int *temp_y = &d->y; + int *temp_z = &d->z; + int **temp_y_ptr = &d->y_ptr; + int **temp_z_ptr = &d->z_ptr; + int **temp_w_ptr = &d->w_ptr; + // 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(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(&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_y_ptr, sizeof(*temp_y_ptr)) != -1); + assert(__msan_test_shadow(temp_z_ptr, sizeof(*temp_z_ptr)) != -1); + assert(__msan_test_shadow(temp_w_ptr, sizeof(*temp_w_ptr)) != -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; +}