1 // RUN: %clangxx_cfi -o %t1 %s 2 // RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s 3 4 // RUN: %clangxx_cfi -DB32 -o %t2 %s 5 // RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s 6 7 // RUN: %clangxx_cfi -DB64 -o %t3 %s 8 // RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s 9 10 // RUN: %clangxx_cfi -DBM -o %t4 %s 11 // RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s 12 13 // RUN: %clangxx_cfi -O1 -o %t5 %s 14 // RUN: %expect_crash %t5 2>&1 | FileCheck --check-prefix=CFI %s 15 16 // RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s 17 // RUN: %expect_crash %t6 2>&1 | FileCheck --check-prefix=CFI %s 18 19 // RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s 20 // RUN: %expect_crash %t7 2>&1 | FileCheck --check-prefix=CFI %s 21 22 // RUN: %clangxx_cfi -O1 -DBM -o %t8 %s 23 // RUN: %expect_crash %t8 2>&1 | FileCheck --check-prefix=CFI %s 24 25 // RUN: %clangxx_cfi -O2 -o %t9 %s 26 // RUN: %expect_crash %t9 2>&1 | FileCheck --check-prefix=CFI %s 27 28 // RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s 29 // RUN: %expect_crash %t10 2>&1 | FileCheck --check-prefix=CFI %s 30 31 // RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s 32 // RUN: %expect_crash %t11 2>&1 | FileCheck --check-prefix=CFI %s 33 34 // RUN: %clangxx_cfi -O2 -DBM -o %t12 %s 35 // RUN: %expect_crash %t12 2>&1 | FileCheck --check-prefix=CFI %s 36 37 // RUN: %clangxx_cfi -O3 -o %t13 %s 38 // RUN: %expect_crash %t13 2>&1 | FileCheck --check-prefix=CFI %s 39 40 // RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s 41 // RUN: %expect_crash %t14 2>&1 | FileCheck --check-prefix=CFI %s 42 43 // RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s 44 // RUN: %expect_crash %t15 2>&1 | FileCheck --check-prefix=CFI %s 45 46 // RUN: %clangxx_cfi -O3 -DBM -o %t16 %s 47 // RUN: %expect_crash %t16 2>&1 | FileCheck --check-prefix=CFI %s 48 49 // RUN: %clangxx_cfi_diag -o %t17 %s 50 // RUN: %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s 51 52 // RUN: %clangxx -o %t18 %s 53 // RUN: %t18 2>&1 | FileCheck --check-prefix=NCFI %s 54 55 // Tests that the CFI mechanism crashes the program when making a virtual call 56 // to an object of the wrong class but with a compatible vtable, by casting a 57 // pointer to such an object and attempting to make a call through it. 58 59 // REQUIRES: cxxabi 60 61 #include <stdio.h> 62 #include "utils.h" 63 64 struct A { 65 virtual void f(); 66 }; 67 68 void A::f() {} 69 70 struct B { 71 virtual void f(); 72 }; 73 74 void B::f() {} 75 76 int main() { 77 create_derivers<B>(); 78 79 A *a = new A; 80 break_optimization(a); 81 82 // CFI: 1 83 // NCFI: 1 84 fprintf(stderr, "1\n"); 85 86 // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type 87 // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' 88 // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call 89 // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' 90 ((B *)a)->f(); // UB here 91 92 // CFI-NOT: {{^2$}} 93 // NCFI: {{^2$}} 94 fprintf(stderr, "2\n"); 95 } 96