blob: 845b9553b24c6cddd4f067f2de82e37e02fbec86 [file] [log] [blame]
Peter Collingbourne6708c4a2015-06-19 01:51:54 +00001// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s
2// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s
3// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast,cfi-cast-strict -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s
Peter Collingbourned2926c92015-03-14 02:42:25 +00004
5// In this test the main thing we are searching for is something like
6// 'metadata !"1B"' where "1B" is the mangled name of the class we are
7// casting to (or maybe its base class in non-strict mode).
8
9struct A {
10 virtual void f();
Peter Collingbourne574975e2016-01-14 02:49:48 +000011 int i() const;
Peter Collingbourned2926c92015-03-14 02:42:25 +000012};
13
14struct B : A {
15 virtual void f();
16};
17
18struct C : A {};
19
20// CHECK-DCAST-LABEL: define void @_Z3abpP1A
21void abp(A *a) {
Peter Collingbourne2c7f7e32015-09-10 02:17:40 +000022 // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
Peter Collingbourne6708c4a2015-06-19 01:51:54 +000023 // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
Peter Collingbourned2926c92015-03-14 02:42:25 +000024
25 // CHECK-DCAST: [[TRAPBB]]
26 // CHECK-DCAST-NEXT: call void @llvm.trap()
27 // CHECK-DCAST-NEXT: unreachable
28
29 // CHECK-DCAST: [[CONTBB]]
30 // CHECK-DCAST: ret
31 static_cast<B*>(a);
32}
33
34// CHECK-DCAST-LABEL: define void @_Z3abrR1A
35void abr(A &a) {
Peter Collingbourne2c7f7e32015-09-10 02:17:40 +000036 // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
Peter Collingbourne6708c4a2015-06-19 01:51:54 +000037 // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
Peter Collingbourned2926c92015-03-14 02:42:25 +000038
39 // CHECK-DCAST: [[TRAPBB]]
40 // CHECK-DCAST-NEXT: call void @llvm.trap()
41 // CHECK-DCAST-NEXT: unreachable
42
43 // CHECK-DCAST: [[CONTBB]]
44 // CHECK-DCAST: ret
45 static_cast<B&>(a);
46}
47
48// CHECK-DCAST-LABEL: define void @_Z4abrrO1A
49void abrr(A &&a) {
Peter Collingbourne2c7f7e32015-09-10 02:17:40 +000050 // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
Peter Collingbourne6708c4a2015-06-19 01:51:54 +000051 // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
Peter Collingbourned2926c92015-03-14 02:42:25 +000052
53 // CHECK-DCAST: [[TRAPBB]]
54 // CHECK-DCAST-NEXT: call void @llvm.trap()
55 // CHECK-DCAST-NEXT: unreachable
56
57 // CHECK-DCAST: [[CONTBB]]
58 // CHECK-DCAST: ret
59 static_cast<B&&>(a);
60}
61
62// CHECK-UCAST-LABEL: define void @_Z3vbpPv
63void vbp(void *p) {
Peter Collingbourne2c7f7e32015-09-10 02:17:40 +000064 // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
Peter Collingbourne6708c4a2015-06-19 01:51:54 +000065 // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
Peter Collingbourned2926c92015-03-14 02:42:25 +000066
67 // CHECK-UCAST: [[TRAPBB]]
68 // CHECK-UCAST-NEXT: call void @llvm.trap()
69 // CHECK-UCAST-NEXT: unreachable
70
71 // CHECK-UCAST: [[CONTBB]]
72 // CHECK-UCAST: ret
73 static_cast<B*>(p);
74}
75
76// CHECK-UCAST-LABEL: define void @_Z3vbrRc
77void vbr(char &r) {
Peter Collingbourne2c7f7e32015-09-10 02:17:40 +000078 // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
Peter Collingbourne6708c4a2015-06-19 01:51:54 +000079 // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
Peter Collingbourned2926c92015-03-14 02:42:25 +000080
81 // CHECK-UCAST: [[TRAPBB]]
82 // CHECK-UCAST-NEXT: call void @llvm.trap()
83 // CHECK-UCAST-NEXT: unreachable
84
85 // CHECK-UCAST: [[CONTBB]]
86 // CHECK-UCAST: ret
87 reinterpret_cast<B&>(r);
88}
89
90// CHECK-UCAST-LABEL: define void @_Z4vbrrOc
91void vbrr(char &&r) {
Peter Collingbourne2c7f7e32015-09-10 02:17:40 +000092 // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
Peter Collingbourne6708c4a2015-06-19 01:51:54 +000093 // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
Peter Collingbourned2926c92015-03-14 02:42:25 +000094
95 // CHECK-UCAST: [[TRAPBB]]
96 // CHECK-UCAST-NEXT: call void @llvm.trap()
97 // CHECK-UCAST-NEXT: unreachable
98
99 // CHECK-UCAST: [[CONTBB]]
100 // CHECK-UCAST: ret
101 reinterpret_cast<B&&>(r);
102}
103
104// CHECK-UCAST-LABEL: define void @_Z3vcpPv
105// CHECK-UCAST-STRICT-LABEL: define void @_Z3vcpPv
106void vcp(void *p) {
Peter Collingbourne574975e2016-01-14 02:49:48 +0000107 // CHECK-UCAST: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
108 // CHECK-UCAST-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
Peter Collingbourned2926c92015-03-14 02:42:25 +0000109 static_cast<C*>(p);
110}
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000111
112// CHECK-UCAST-LABEL: define void @_Z3bcpP1B
113// CHECK-UCAST-STRICT-LABEL: define void @_Z3bcpP1B
114void bcp(B *p) {
Peter Collingbourne574975e2016-01-14 02:49:48 +0000115 // CHECK-UCAST: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
116 // CHECK-UCAST-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000117 (C *)p;
118}
119
120// CHECK-UCAST-LABEL: define void @_Z8bcp_callP1B
121// CHECK-UCAST-STRICT-LABEL: define void @_Z8bcp_callP1B
122void bcp_call(B *p) {
Peter Collingbourne574975e2016-01-14 02:49:48 +0000123 // CHECK-UCAST: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
124 // CHECK-UCAST-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000125 ((C *)p)->f();
126}
Peter Collingbourne574975e2016-01-14 02:49:48 +0000127
128// CHECK-UCAST-LABEL: define i32 @_Z6a_callP1A
129// CHECK-UCAST-STRICT-LABEL: define i32 @_Z6a_callP1A
130int a_call(A *a) {
131 // CHECK-UCAST-NOT: @llvm.bitset.test
132 // CHECK-UCAST-STRICT-NOT: @llvm.bitset.test
133 return a->i();
134}