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 122 123 124 125 126
|
// -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();
}
|