xref: /aosp_15_r20/external/compiler-rt/test/msan/dtor-vtable-multiple-inheritance.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
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 -DCVPTR=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 -DEAVPTR=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 -DEDVPTR=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 // Expected to quit due to invalid access when invoking
14*7c3d14c8STreehugger Robot // function using vtable.
15*7c3d14c8STreehugger Robot 
16*7c3d14c8STreehugger Robot class A {
17*7c3d14c8STreehugger Robot  public:
18*7c3d14c8STreehugger Robot   int x;
~A()19*7c3d14c8STreehugger Robot   virtual ~A() {
20*7c3d14c8STreehugger Robot     // Should succeed
21*7c3d14c8STreehugger Robot     this->A_Foo();
22*7c3d14c8STreehugger Robot   }
A_Foo()23*7c3d14c8STreehugger Robot   virtual void A_Foo() {}
24*7c3d14c8STreehugger Robot };
25*7c3d14c8STreehugger Robot 
26*7c3d14c8STreehugger Robot class B : public virtual A {
27*7c3d14c8STreehugger Robot  public:
28*7c3d14c8STreehugger Robot   int y;
~B()29*7c3d14c8STreehugger Robot   virtual ~B() {}
A_Foo()30*7c3d14c8STreehugger Robot   virtual void A_Foo() {}
31*7c3d14c8STreehugger Robot };
32*7c3d14c8STreehugger Robot 
33*7c3d14c8STreehugger Robot class C : public B {
34*7c3d14c8STreehugger Robot  public:
35*7c3d14c8STreehugger Robot   int z;
~C()36*7c3d14c8STreehugger Robot   ~C() {}
37*7c3d14c8STreehugger Robot };
38*7c3d14c8STreehugger Robot 
39*7c3d14c8STreehugger Robot class D {
40*7c3d14c8STreehugger Robot  public:
41*7c3d14c8STreehugger Robot   int w;
~D()42*7c3d14c8STreehugger Robot   ~D() {}
D_Foo()43*7c3d14c8STreehugger Robot   virtual void D_Foo() {}
44*7c3d14c8STreehugger Robot };
45*7c3d14c8STreehugger Robot 
46*7c3d14c8STreehugger Robot class E : public virtual A, public virtual D {
47*7c3d14c8STreehugger Robot  public:
48*7c3d14c8STreehugger Robot   int u;
~E()49*7c3d14c8STreehugger Robot   ~E() {}
A_Foo()50*7c3d14c8STreehugger Robot   void A_Foo() {}
51*7c3d14c8STreehugger Robot };
52*7c3d14c8STreehugger Robot 
main()53*7c3d14c8STreehugger Robot int main() {
54*7c3d14c8STreehugger Robot   // Simple linear inheritance
55*7c3d14c8STreehugger Robot   C *c = new C();
56*7c3d14c8STreehugger Robot   c->~C();
57*7c3d14c8STreehugger Robot   // This fails
58*7c3d14c8STreehugger Robot #ifdef CVPTR
59*7c3d14c8STreehugger Robot   c->A_Foo();
60*7c3d14c8STreehugger Robot #endif
61*7c3d14c8STreehugger Robot 
62*7c3d14c8STreehugger Robot   // Multiple inheritance, so has multiple vtables
63*7c3d14c8STreehugger Robot   E *e = new E();
64*7c3d14c8STreehugger Robot   e->~E();
65*7c3d14c8STreehugger Robot   // Both of these fail
66*7c3d14c8STreehugger Robot #ifdef EAVPTR
67*7c3d14c8STreehugger Robot   e->A_Foo();
68*7c3d14c8STreehugger Robot #endif
69*7c3d14c8STreehugger Robot #ifdef EDVPTR
70*7c3d14c8STreehugger Robot   e->D_Foo();
71*7c3d14c8STreehugger Robot #endif
72*7c3d14c8STreehugger Robot }
73