1 // UNSUPPORTED: target={{.*windows-msvc.*}}
3 // RUN: %clangxx_cfi -o %t %s
4 // RUN: %expect_crash %run %t a
5 // RUN: %expect_crash %run %t b
6 // RUN: %expect_crash %run %t c
7 // RUN: %expect_crash %run %t d
8 // RUN: %expect_crash %run %t e
12 // RUN: %clangxx_cfi_diag -o %t2 %s
13 // RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
14 // RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
15 // RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
16 // RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
17 // RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
30 struct S
: SBase1
, SBase2
{
32 int f2() { return 1; }
34 virtual int g2() { return 1; }
35 virtual int g3() { return 1; }
40 int f2() { return 2; }
42 virtual int g2() { return 2; }
46 typedef void (S::*S_void
)();
48 typedef int (S::*S_int
)();
49 typedef int (T::*T_int
)();
51 template <typename To
, typename From
>
53 assert(sizeof(To
) == sizeof(From
));
55 memcpy(&t
, &f
, sizeof(f
));
59 int main(int argc
, char **argv
) {
65 // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
66 // A: note: S::f1() defined here
67 (s
.*bitcast
<S_int
>(&S::f1
))();
70 // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
71 // B: note: S::f2() defined here
72 (t
.*bitcast
<T_int
>(&S::f2
))();
75 // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
76 // C: note: vtable is of type 'S'
77 (s
.*bitcast
<S_int
>(&S::g1
))();
80 // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
81 // D: note: vtable is of type 'T'
82 (reinterpret_cast<S
&>(t
).*&S::g2
)();
85 // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
86 // E: note: vtable is of type 'S'
87 (s
.*bitcast
<S_void
>(&T::g3
))();