diff options
Diffstat (limited to 'test/msan/dtor-vtable-multiple-inheritance.cc')
-rw-r--r-- | test/msan/dtor-vtable-multiple-inheritance.cc | 72 |
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 +} |