summaryrefslogtreecommitdiff
path: root/test/msan/dtor-vtable-multiple-inheritance.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/msan/dtor-vtable-multiple-inheritance.cc')
-rw-r--r--test/msan/dtor-vtable-multiple-inheritance.cc72
1 files changed, 72 insertions, 0 deletions
diff --git a/test/msan/dtor-vtable-multiple-inheritance.cc b/test/msan/dtor-vtable-multiple-inheritance.cc
new file mode 100644
index 0000000000000..8521fadd0725f
--- /dev/null
+++ b/test/msan/dtor-vtable-multiple-inheritance.cc
@@ -0,0 +1,72 @@
+// 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 -DCVPTR=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t
+
+// RUN: %clangxx_msan %s -DEAVPTR=1 -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t
+
+// RUN: %clangxx_msan %s -DEDVPTR=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.
+
+class A {
+ public:
+ int x;
+ virtual ~A() {
+ // Should succeed
+ this->A_Foo();
+ }
+ virtual void A_Foo() {}
+};
+
+class B : public virtual A {
+ public:
+ int y;
+ virtual ~B() {}
+ virtual void A_Foo() {}
+};
+
+class C : public B {
+ public:
+ int z;
+ ~C() {}
+};
+
+class D {
+ public:
+ int w;
+ ~D() {}
+ virtual void D_Foo() {}
+};
+
+class E : public virtual A, public virtual D {
+ public:
+ int u;
+ ~E() {}
+ void A_Foo() {}
+};
+
+int main() {
+ // Simple linear inheritance
+ C *c = new C();
+ c->~C();
+ // This fails
+#ifdef CVPTR
+ c->A_Foo();
+#endif
+
+ // Multiple inheritance, so has multiple vtables
+ E *e = new E();
+ e->~E();
+ // Both of these fail
+#ifdef EAVPTR
+ e->A_Foo();
+#endif
+#ifdef EDVPTR
+ e->D_Foo();
+#endif
+}