| // -mretpoline does not work yet on Darwin. | |
| // XFAIL: darwin | |
| // RUN: %clangxx_cfi -o %t %s | |
| // RUN: %run %t | |
| // RUN: %clangxx_cfi -mretpoline -o %t2 %s | |
| // RUN: %run %t2 | |
| // Tests that the CFI mechanism does not crash the program when making various | |
| // kinds of valid calls involving classes with various different linkages and | |
| // types of inheritance, and both virtual and non-virtual member functions. | |
| #include "utils.h" | |
| struct A { | |
| virtual void f(); | |
| void g(); | |
| }; | |
| void A::f() {} | |
| void A::g() {} | |
| struct A2 : A { | |
| virtual void f(); | |
| void g(); | |
| }; | |
| void A2::f() {} | |
| void A2::g() {} | |
| struct B { | |
| virtual void f() {} | |
| void g() {} | |
| }; | |
| struct B2 : B { | |
| virtual void f() {} | |
| void g() {} | |
| }; | |
| namespace { | |
| struct C { | |
| virtual void f(); | |
| void g(); | |
| }; | |
| void C::f() {} | |
| void C::g() {} | |
| struct C2 : C { | |
| virtual void f(); | |
| void g(); | |
| }; | |
| void C2::f() {} | |
| void C2::g() {} | |
| struct D { | |
| virtual void f() {} | |
| void g() {} | |
| }; | |
| struct D2 : D { | |
| virtual void f() {} | |
| void g() {} | |
| }; | |
| } | |
| struct E { | |
| virtual void f() {} | |
| void g() {} | |
| }; | |
| struct E2 : virtual E { | |
| virtual void f() {} | |
| void g() {} | |
| }; | |
| int main() { | |
| A *a = new A; | |
| break_optimization(a); | |
| a->f(); | |
| a->g(); | |
| a = new A2; | |
| break_optimization(a); | |
| a->f(); | |
| a->g(); | |
| B *b = new B; | |
| break_optimization(b); | |
| b->f(); | |
| b->g(); | |
| b = new B2; | |
| break_optimization(b); | |
| b->f(); | |
| b->g(); | |
| C *c = new C; | |
| break_optimization(c); | |
| c->f(); | |
| c->g(); | |
| c = new C2; | |
| break_optimization(c); | |
| c->f(); | |
| c->g(); | |
| D *d = new D; | |
| break_optimization(d); | |
| d->f(); | |
| d->g(); | |
| d = new D2; | |
| break_optimization(d); | |
| d->f(); | |
| d->g(); | |
| E *e = new E; | |
| break_optimization(e); | |
| e->f(); | |
| e->g(); | |
| e = new E2; | |
| break_optimization(e); | |
| e->f(); | |
| e->g(); | |
| } |