• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
f()71 void A::f() {}
72 
73 struct B : A {
74   virtual void f();
75 };
76 
f()77 void B::f() {}
78 
79 struct C : A {
80 };
81 
main(int argc,char ** argv)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