1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
| // RUN: %clangxx_cfi -o %t %s
| // RUN: %t
|
| // 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();
| }
|
|