1 // UNSUPPORTED: windows-msvc 2 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 9 // RUN: %run %t f 10 // RUN: %run %t g 11 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 18 19 #include <assert.h> 20 #include <string.h> 21 22 struct SBase1 { 23 void b1() {} 24 }; 25 26 struct SBase2 { 27 void b2() {} 28 }; 29 30 struct S : SBase1, SBase2 { 31 void f1() {} 32 int f2() { return 1; } 33 virtual void g1() {} 34 virtual int g2() { return 1; } 35 virtual int g3() { return 1; } 36 }; 37 38 struct T { 39 void f1() {} 40 int f2() { return 2; } 41 virtual void g1() {} 42 virtual int g2() { return 2; } 43 virtual void g3() {} 44 }; 45 46 typedef void (S::*S_void)(); 47 48 typedef int (S::*S_int)(); 49 typedef int (T::*T_int)(); 50 51 template <typename To, typename From> 52 To bitcast(From f) { 53 assert(sizeof(To) == sizeof(From)); 54 To t; 55 memcpy(&t, &f, sizeof(f)); 56 return t; 57 } 58 59 int main(int argc, char **argv) { 60 S s; 61 T t; 62 63 switch (argv[1][0]) { 64 case 'a': 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))(); 68 break; 69 case 'b': 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))(); 73 break; 74 case 'c': 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))(); 78 break; 79 case 'd': 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)(); 83 break; 84 case 'e': 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))(); 88 break; 89 case 'f': 90 (s.*&SBase1::b1)(); 91 break; 92 case 'g': 93 (s.*&SBase2::b2)(); 94 break; 95 } 96 } 97