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