1 // RUN: %clangxx_cfi -o %t %s
2 // RUN: %expect_crash %run %t a
3 // RUN: %expect_crash %run %t b
4 // RUN: %expect_crash %run %t c
5 // RUN: %expect_crash %run %t d
6 // RUN: %expect_crash %run %t e
7 // RUN: %run %t f
8 // RUN: %run %t g
9 
10 // RUN: %clangxx_cfi_diag -o %t2 %s
11 // RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
12 // RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
13 // RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
14 // RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
15 // RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
16 
17 #include <assert.h>
18 #include <string.h>
19 
20 struct SBase1 {
21   void b1() {}
22 };
23 
24 struct SBase2 {
25   void b2() {}
26 };
27 
28 struct S : SBase1, SBase2 {
29   void f1() {}
30   int f2() { return 1; }
31   virtual void g1() {}
32   virtual int g2() { return 1; }
33   virtual int g3() { return 1; }
34 };
35 
36 struct T {
37   void f1() {}
38   int f2() { return 2; }
39   virtual void g1() {}
40   virtual int g2() { return 2; }
41   virtual void g3() {}
42 };
43 
44 typedef void (S::*S_void)();
45 
46 typedef int (S::*S_int)();
47 typedef int (T::*T_int)();
48 
49 template <typename To, typename From>
50 To bitcast(From f) {
51   assert(sizeof(To) == sizeof(From));
52   To t;
53   memcpy(&t, &f, sizeof(f));
54   return t;
55 }
56 
57 int main(int argc, char **argv) {
58   S s;
59   T t;
60 
61   switch (argv[1][0]) {
62     case 'a':
63       // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
64       // A: note: S::f1() defined here
65       (s.*bitcast<S_int>(&S::f1))();
66       break;
67     case 'b':
68       // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
69       // B: note: S::f2() defined here
70       (t.*bitcast<T_int>(&S::f2))();
71       break;
72     case 'c':
73       // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
74       // C: note: vtable is of type 'S'
75       (s.*bitcast<S_int>(&S::g1))();
76       break;
77     case 'd':
78       // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
79       // D: note: vtable is of type 'T'
80       (reinterpret_cast<S &>(t).*&S::g2)();
81       break;
82     case 'e':
83       // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
84       // E: note: vtable is of type 'S'
85       (s.*bitcast<S_void>(&T::g3))();
86       break;
87     case 'f':
88       (s.*&SBase1::b1)();
89       break;
90     case 'g':
91       (s.*&SBase2::b2)();
92       break;
93   }
94 }
95