1 // -mretpoline does not work yet on Darwin. 2 // XFAIL: darwin 3 4 // RUN: %clangxx_cfi -o %t %s 5 // RUN: %run %t 6 // RUN: %clangxx_cfi -mretpoline -o %t2 %s 7 // RUN: %run %t2 8 9 // Tests that the CFI mechanism does not crash the program when making various 10 // kinds of valid calls involving classes with various different linkages and 11 // types of inheritance, and both virtual and non-virtual member functions. 12 13 #include "utils.h" 14 15 struct A { 16 virtual void f(); 17 void g(); 18 }; 19 20 void A::f() {} 21 void A::g() {} 22 23 struct A2 : A { 24 virtual void f(); 25 void g(); 26 }; 27 28 void A2::f() {} 29 void A2::g() {} 30 31 struct B { 32 virtual void f() {} 33 void g() {} 34 }; 35 36 struct B2 : B { 37 virtual void f() {} 38 void g() {} 39 }; 40 41 namespace { 42 43 struct C { 44 virtual void f(); 45 void g(); 46 }; 47 48 void C::f() {} 49 void C::g() {} 50 51 struct C2 : C { 52 virtual void f(); 53 void g(); 54 }; 55 56 void C2::f() {} 57 void C2::g() {} 58 59 struct D { 60 virtual void f() {} 61 void g() {} 62 }; 63 64 struct D2 : D { 65 virtual void f() {} 66 void g() {} 67 }; 68 69 } 70 71 struct E { 72 virtual void f() {} 73 void g() {} 74 }; 75 76 struct E2 : virtual E { 77 virtual void f() {} 78 void g() {} 79 }; 80 81 int main() { 82 A *a = new A; 83 break_optimization(a); 84 a->f(); 85 a->g(); 86 a = new A2; 87 break_optimization(a); 88 a->f(); 89 a->g(); 90 91 B *b = new B; 92 break_optimization(b); 93 b->f(); 94 b->g(); 95 b = new B2; 96 break_optimization(b); 97 b->f(); 98 b->g(); 99 100 C *c = new C; 101 break_optimization(c); 102 c->f(); 103 c->g(); 104 c = new C2; 105 break_optimization(c); 106 c->f(); 107 c->g(); 108 109 D *d = new D; 110 break_optimization(d); 111 d->f(); 112 d->g(); 113 d = new D2; 114 break_optimization(d); 115 d->f(); 116 d->g(); 117 118 E *e = new E; 119 break_optimization(e); 120 e->f(); 121 e->g(); 122 e = new E2; 123 break_optimization(e); 124 e->f(); 125 e->g(); 126 } 127