1*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 2*7c3d14c8STreehugger Robot 3*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 4*7c3d14c8STreehugger Robot 5*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 6*7c3d14c8STreehugger Robot 7*7c3d14c8STreehugger Robot // 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 8*7c3d14c8STreehugger Robot 9*7c3d14c8STreehugger Robot // 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 10*7c3d14c8STreehugger Robot 11*7c3d14c8STreehugger Robot // 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 12*7c3d14c8STreehugger Robot 13*7c3d14c8STreehugger Robot // 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 14*7c3d14c8STreehugger Robot 15*7c3d14c8STreehugger Robot // Expected to quit due to invalid access when invoking 16*7c3d14c8STreehugger Robot // function using vtable. 17*7c3d14c8STreehugger Robot 18*7c3d14c8STreehugger Robot #include <sanitizer/msan_interface.h> 19*7c3d14c8STreehugger Robot #include <stdio.h> 20*7c3d14c8STreehugger Robot #include <assert.h> 21*7c3d14c8STreehugger Robot 22*7c3d14c8STreehugger Robot class A { 23*7c3d14c8STreehugger Robot public: 24*7c3d14c8STreehugger Robot int x; ~A()25*7c3d14c8STreehugger Robot ~A() {} A_Foo()26*7c3d14c8STreehugger Robot virtual void A_Foo() {} 27*7c3d14c8STreehugger Robot }; 28*7c3d14c8STreehugger Robot 29*7c3d14c8STreehugger Robot class B { 30*7c3d14c8STreehugger Robot public: 31*7c3d14c8STreehugger Robot int y; ~B()32*7c3d14c8STreehugger Robot ~B() {} B_Foo()33*7c3d14c8STreehugger Robot virtual void B_Foo() {} 34*7c3d14c8STreehugger Robot }; 35*7c3d14c8STreehugger Robot 36*7c3d14c8STreehugger Robot class C : public A, public B { 37*7c3d14c8STreehugger Robot public: 38*7c3d14c8STreehugger Robot int z; ~C()39*7c3d14c8STreehugger Robot ~C() {} C_Foo()40*7c3d14c8STreehugger Robot virtual void C_Foo() {} 41*7c3d14c8STreehugger Robot }; 42*7c3d14c8STreehugger Robot main()43*7c3d14c8STreehugger Robotint main() { 44*7c3d14c8STreehugger Robot A *a = new A(); 45*7c3d14c8STreehugger Robot a->~A(); 46*7c3d14c8STreehugger Robot 47*7c3d14c8STreehugger Robot // Shouldn't be allowed to invoke function via vtable. 48*7c3d14c8STreehugger Robot #ifdef VPTRA 49*7c3d14c8STreehugger Robot a->A_Foo(); 50*7c3d14c8STreehugger Robot #endif 51*7c3d14c8STreehugger Robot 52*7c3d14c8STreehugger Robot C *c = new C(); 53*7c3d14c8STreehugger Robot c->~C(); 54*7c3d14c8STreehugger Robot 55*7c3d14c8STreehugger Robot #ifdef VPTRCA 56*7c3d14c8STreehugger Robot c->A_Foo(); 57*7c3d14c8STreehugger Robot #endif 58*7c3d14c8STreehugger Robot 59*7c3d14c8STreehugger Robot #ifdef VPTRCB 60*7c3d14c8STreehugger Robot c->B_Foo(); 61*7c3d14c8STreehugger Robot #endif 62*7c3d14c8STreehugger Robot 63*7c3d14c8STreehugger Robot #ifdef VPTRC 64*7c3d14c8STreehugger Robot c->C_Foo(); 65*7c3d14c8STreehugger Robot #endif 66*7c3d14c8STreehugger Robot 67*7c3d14c8STreehugger Robot return 0; 68*7c3d14c8STreehugger Robot } 69