aboutsummaryrefslogtreecommitdiff
path: root/test/msan/dtor-vtable.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/msan/dtor-vtable.cc')
-rw-r--r--test/msan/dtor-vtable.cc68
1 files changed, 68 insertions, 0 deletions
diff --git a/test/msan/dtor-vtable.cc b/test/msan/dtor-vtable.cc
new file mode 100644
index 000000000000..9bbad26092d6
--- /dev/null
+++ b/test/msan/dtor-vtable.cc
@@ -0,0 +1,68 @@
+// 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
+
+// RUN: %clangxx_msan %s -DVPTRA=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t
+
+// RUN: %clangxx_msan %s -DVPTRCA=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t
+
+// RUN: %clangxx_msan %s -DVPTRCB=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t
+
+// RUN: %clangxx_msan %s -DVPTRC=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t
+
+// Expected to quit due to invalid access when invoking
+// function using vtable.
+
+#include <sanitizer/msan_interface.h>
+#include <stdio.h>
+#include <assert.h>
+
+class A {
+public:
+ int x;
+ ~A() {}
+ virtual void A_Foo() {}
+};
+
+class B {
+ public:
+ int y;
+ ~B() {}
+ virtual void B_Foo() {}
+};
+
+class C : public A, public B {
+ public:
+ int z;
+ ~C() {}
+ virtual void C_Foo() {}
+};
+
+int main() {
+ A *a = new A();
+ a->~A();
+
+ // Shouldn't be allowed to invoke function via vtable.
+#ifdef VPTRA
+ a->A_Foo();
+#endif
+
+ C *c = new C();
+ c->~C();
+
+#ifdef VPTRCA
+ c->A_Foo();
+#endif
+
+#ifdef VPTRCB
+ c->B_Foo();
+#endif
+
+#ifdef VPTRC
+ c->C_Foo();
+#endif
+
+ return 0;
+}