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