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
15struct A {
16 virtual void f();
17 void g();
18};
19
20void A::f() {}
21void A::g() {}
22
23struct A2 : A {
24 virtual void f();
25 void g();
26};
27
28void A2::f() {}
29void A2::g() {}
30
31struct B {
32 virtual void f() {}
33 void g() {}
34};
35
36struct B2 : B {
37 virtual void f() {}
38 void g() {}
39};
40
41namespace {
42
43struct C {
44 virtual void f();
45 void g();
46};
47
48void C::f() {}
49void C::g() {}
50
51struct C2 : C {
52 virtual void f();
53 void g();
54};
55
56void C2::f() {}
57void C2::g() {}
58
59struct D {
60 virtual void f() {}
61 void g() {}
62};
63
64struct D2 : D {
65 virtual void f() {}
66 void g() {}
67};
68
69}
70
71struct E {
72 virtual void f() {}
73 void g() {}
74};
75
76struct E2 : virtual E {
77 virtual void f() {}
78 void g() {}
79};
80
81int 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