1 // RUN: %clangxx_cfi -o %t1 %s 2 // RUN: %expect_crash %t1 a 2>&1 | FileCheck --check-prefix=FAIL %s 3 // RUN: %expect_crash %t1 b 2>&1 | FileCheck --check-prefix=FAIL %s 4 // RUN: %expect_crash %t1 c 2>&1 | FileCheck --check-prefix=FAIL %s 5 // RUN: %t1 d 2>&1 | FileCheck --check-prefix=PASS %s 6 // RUN: %t1 e 2>&1 | FileCheck --check-prefix=PASS %s 7 // RUN: %t1 f 2>&1 | FileCheck --check-prefix=PASS %s 8 // RUN: %expect_crash %t1 g 2>&1 | FileCheck --check-prefix=FAIL %s 9 // RUN: %t1 h 2>&1 | FileCheck --check-prefix=PASS %s 10 11 // RUN: %clangxx_cfi -DB32 -o %t2 %s 12 // RUN: %expect_crash %t2 a 2>&1 | FileCheck --check-prefix=FAIL %s 13 // RUN: %expect_crash %t2 b 2>&1 | FileCheck --check-prefix=FAIL %s 14 // RUN: %expect_crash %t2 c 2>&1 | FileCheck --check-prefix=FAIL %s 15 // RUN: %t2 d 2>&1 | FileCheck --check-prefix=PASS %s 16 // RUN: %t2 e 2>&1 | FileCheck --check-prefix=PASS %s 17 // RUN: %t2 f 2>&1 | FileCheck --check-prefix=PASS %s 18 // RUN: %expect_crash %t2 g 2>&1 | FileCheck --check-prefix=FAIL %s 19 // RUN: %t2 h 2>&1 | FileCheck --check-prefix=PASS %s 20 21 // RUN: %clangxx_cfi -DB64 -o %t3 %s 22 // RUN: %expect_crash %t3 a 2>&1 | FileCheck --check-prefix=FAIL %s 23 // RUN: %expect_crash %t3 b 2>&1 | FileCheck --check-prefix=FAIL %s 24 // RUN: %expect_crash %t3 c 2>&1 | FileCheck --check-prefix=FAIL %s 25 // RUN: %t3 d 2>&1 | FileCheck --check-prefix=PASS %s 26 // RUN: %t3 e 2>&1 | FileCheck --check-prefix=PASS %s 27 // RUN: %t3 f 2>&1 | FileCheck --check-prefix=PASS %s 28 // RUN: %expect_crash %t3 g 2>&1 | FileCheck --check-prefix=FAIL %s 29 // RUN: %t3 h 2>&1 | FileCheck --check-prefix=PASS %s 30 31 // RUN: %clangxx_cfi -DBM -o %t4 %s 32 // RUN: %expect_crash %t4 a 2>&1 | FileCheck --check-prefix=FAIL %s 33 // RUN: %expect_crash %t4 b 2>&1 | FileCheck --check-prefix=FAIL %s 34 // RUN: %expect_crash %t4 c 2>&1 | FileCheck --check-prefix=FAIL %s 35 // RUN: %t4 d 2>&1 | FileCheck --check-prefix=PASS %s 36 // RUN: %t4 e 2>&1 | FileCheck --check-prefix=PASS %s 37 // RUN: %t4 f 2>&1 | FileCheck --check-prefix=PASS %s 38 // RUN: %expect_crash %t4 g 2>&1 | FileCheck --check-prefix=FAIL %s 39 // RUN: %t4 h 2>&1 | FileCheck --check-prefix=PASS %s 40 41 // RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t5 %s 42 // RUN: %expect_crash %t5 a 2>&1 | FileCheck --check-prefix=FAIL %s 43 // RUN: %expect_crash %t5 b 2>&1 | FileCheck --check-prefix=FAIL %s 44 // RUN: %expect_crash %t5 c 2>&1 | FileCheck --check-prefix=FAIL %s 45 // RUN: %expect_crash %t5 d 2>&1 | FileCheck --check-prefix=FAIL %s 46 // RUN: %expect_crash %t5 e 2>&1 | FileCheck --check-prefix=FAIL %s 47 // RUN: %expect_crash %t5 f 2>&1 | FileCheck --check-prefix=FAIL %s 48 // RUN: %expect_crash %t5 g 2>&1 | FileCheck --check-prefix=FAIL %s 49 // RUN: %expect_crash %t5 h 2>&1 | FileCheck --check-prefix=FAIL %s 50 51 // RUN: %clangxx -o %t6 %s 52 // RUN: %t6 a 2>&1 | FileCheck --check-prefix=PASS %s 53 // RUN: %t6 b 2>&1 | FileCheck --check-prefix=PASS %s 54 // RUN: %t6 c 2>&1 | FileCheck --check-prefix=PASS %s 55 // RUN: %t6 d 2>&1 | FileCheck --check-prefix=PASS %s 56 // RUN: %t6 e 2>&1 | FileCheck --check-prefix=PASS %s 57 // RUN: %t6 f 2>&1 | FileCheck --check-prefix=PASS %s 58 // RUN: %t6 g 2>&1 | FileCheck --check-prefix=PASS %s 59 // RUN: %t6 h 2>&1 | FileCheck --check-prefix=PASS %s 60 61 // RUN: %clangxx_cfi_diag -o %t7 %s 62 // RUN: %t7 a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s 63 // RUN: %t7 b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s 64 // RUN: %t7 c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s 65 // RUN: %t7 g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s 66 67 // Tests that the CFI enforcement detects bad casts. 68 69 // REQUIRES: cxxabi 70 71 #include <stdio.h> 72 #include "utils.h" 73 74 struct A { 75 virtual void f(); 76 }; 77 78 void A::f() {} 79 80 struct B : A { 81 virtual void f(); 82 }; 83 84 void B::f() {} 85 86 struct C : A { 87 }; 88 89 int main(int argc, char **argv) { 90 create_derivers<B>(); 91 92 B *b = new B; 93 break_optimization(b); 94 95 // FAIL: 1 96 // PASS: 1 97 fprintf(stderr, "1\n"); 98 99 A a; 100 101 // CFI-DIAG-D: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast 102 // CFI-DIAG-D-NEXT: note: vtable is of type '{{(struct )?}}A' 103 104 // CFI-DIAG-U: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type 105 // CFI-DIAG-U-NEXT: note: vtable is of type '{{(struct )?}}A' 106 107 switch (argv[1][0]) { 108 case 'a': 109 static_cast<B *>(&a); // UB 110 break; 111 case 'b': 112 static_cast<B &>(a); // UB 113 break; 114 case 'c': 115 static_cast<B &&>(a); // UB 116 break; 117 case 'd': 118 static_cast<C *>(&a); // UB, strict only 119 break; 120 case 'e': 121 static_cast<C &>(a); // UB, strict only 122 break; 123 case 'f': 124 static_cast<C &&>(a); // UB, strict only 125 break; 126 case 'g': 127 static_cast<B *>(static_cast<void *>(&a)); // Non-UB bad cast 128 break; 129 case 'h': 130 static_cast<C *>(static_cast<void *>(&a)); // Non-UB bad cast, strict only 131 break; 132 } 133 134 // FAIL-NOT: {{^2$}} 135 // PASS: {{^2$}} 136 fprintf(stderr, "2\n"); 137 } 138