1 // RUN: %clangxx_cfi -o %t %s 2 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 3 4 // RUN: %clangxx_cfi -DB32 -o %t %s 5 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 6 7 // RUN: %clangxx_cfi -DB64 -o %t %s 8 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 9 10 // RUN: %clangxx_cfi -DBM -o %t %s 11 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 12 13 // RUN: %clangxx_cfi -O1 -o %t %s 14 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 15 16 // RUN: %clangxx_cfi -O1 -DB32 -o %t %s 17 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 18 19 // RUN: %clangxx_cfi -O1 -DB64 -o %t %s 20 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 21 22 // RUN: %clangxx_cfi -O1 -DBM -o %t %s 23 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 24 25 // RUN: %clangxx_cfi -O2 -o %t %s 26 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 27 28 // RUN: %clangxx_cfi -O2 -DB32 -o %t %s 29 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 30 31 // RUN: %clangxx_cfi -O2 -DB64 -o %t %s 32 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 33 34 // RUN: %clangxx_cfi -O2 -DBM -o %t %s 35 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 36 37 // RUN: %clangxx_cfi -O3 -o %t %s 38 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 39 40 // RUN: %clangxx_cfi -O3 -DB32 -o %t %s 41 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 42 43 // RUN: %clangxx_cfi -O3 -DB64 -o %t %s 44 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 45 46 // RUN: %clangxx_cfi -O3 -DBM -o %t %s 47 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 48 49 // RUN: %clangxx -o %t %s 50 // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s 51 52 // Tests that the CFI mechanism crashes the program when making a virtual call 53 // to an object of the wrong class but with a compatible vtable, by casting a 54 // pointer to such an object and attempting to make a call through it. 55 56 #include <stdio.h> 57 #include "utils.h" 58 59 struct A { 60 virtual void f(); 61 }; 62 63 void A::f() {} 64 65 struct B { 66 virtual void f(); 67 }; 68 69 void B::f() {} 70 71 int main() { 72 #ifdef B32 73 break_optimization(new Deriver<B, 0>); 74 #endif 75 76 #ifdef B64 77 break_optimization(new Deriver<B, 0>); 78 break_optimization(new Deriver<B, 1>); 79 #endif 80 81 #ifdef BM 82 break_optimization(new Deriver<B, 0>); 83 break_optimization(new Deriver<B, 1>); 84 break_optimization(new Deriver<B, 2>); 85 #endif 86 87 A *a = new A; 88 break_optimization(a); 89 90 // CFI: 1 91 // NCFI: 1 92 fprintf(stderr, "1\n"); 93 94 ((B *)a)->f(); // UB here 95 96 // CFI-NOT: 2 97 // NCFI: 2 98 fprintf(stderr, "2\n"); 99 } 100