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