test case for poisoning trivial members
authorNaomi Musgrave <nmusgrave@google.com>
Mon, 10 Aug 2015 22:39:09 +0000 (22:39 +0000)
committerNaomi Musgrave <nmusgrave@google.com>
Mon, 10 Aug 2015 22:39:09 +0000 (22:39 +0000)
Summary:
A virtual base class and derived class should only poison their
respective members upon destruction. In particular, trivial members should
be poisoned directly, non-trivial members should be poisoned by their
respective destructors, and references to non-trivial members should be
poisoned.

Reviewers: eugenis, kcc

Differential Revision: http://reviews.llvm.org/D11912

Test case avoids casting to access members

Run configurations to reflect expected runtime failure on assertions.

Simplified access to internal members.

Updated internal member structure of base.

Revised assert in main to verify successful poisoning after dtor.

Verify address of pointer is poisoned.

Fixed assert err.

Cleaned up test by removing extraneous prints, asserts.

llvm-svn: 244521

compiler-rt/test/msan/dtor-base-access.cc [new file with mode: 0644]

diff --git a/compiler-rt/test/msan/dtor-base-access.cc b/compiler-rt/test/msan/dtor-base-access.cc
new file mode 100644 (file)
index 0000000..dd1c0d6
--- /dev/null
@@ -0,0 +1,51 @@
+// 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 <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;
+}