xref: /aosp_15_r20/external/clang/test/CodeGenCXX/cfi-cast.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s
3*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -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
4*67e74705SXin Li 
5*67e74705SXin Li // In this test the main thing we are searching for is something like
6*67e74705SXin Li // 'metadata !"1B"' where "1B" is the mangled name of the class we are
7*67e74705SXin Li // casting to (or maybe its base class in non-strict mode).
8*67e74705SXin Li 
9*67e74705SXin Li struct A {
10*67e74705SXin Li   virtual void f();
11*67e74705SXin Li   int i() const;
12*67e74705SXin Li };
13*67e74705SXin Li 
14*67e74705SXin Li struct B : A {
15*67e74705SXin Li   virtual void f();
16*67e74705SXin Li };
17*67e74705SXin Li 
18*67e74705SXin Li struct C : A {};
19*67e74705SXin Li 
20*67e74705SXin Li // CHECK-DCAST-LABEL: define hidden void @_Z3abpP1A
abp(A * a)21*67e74705SXin Li void abp(A *a) {
22*67e74705SXin Li   // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
23*67e74705SXin Li   // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
24*67e74705SXin Li 
25*67e74705SXin Li   // CHECK-DCAST: [[TRAPBB]]
26*67e74705SXin Li   // CHECK-DCAST-NEXT: call void @llvm.trap()
27*67e74705SXin Li   // CHECK-DCAST-NEXT: unreachable
28*67e74705SXin Li 
29*67e74705SXin Li   // CHECK-DCAST: [[CONTBB]]
30*67e74705SXin Li   // CHECK-DCAST: ret
31*67e74705SXin Li   (void)static_cast<B*>(a);
32*67e74705SXin Li }
33*67e74705SXin Li 
34*67e74705SXin Li // CHECK-DCAST-LABEL: define hidden void @_Z3abrR1A
abr(A & a)35*67e74705SXin Li void abr(A &a) {
36*67e74705SXin Li   // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
37*67e74705SXin Li   // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
38*67e74705SXin Li 
39*67e74705SXin Li   // CHECK-DCAST: [[TRAPBB]]
40*67e74705SXin Li   // CHECK-DCAST-NEXT: call void @llvm.trap()
41*67e74705SXin Li   // CHECK-DCAST-NEXT: unreachable
42*67e74705SXin Li 
43*67e74705SXin Li   // CHECK-DCAST: [[CONTBB]]
44*67e74705SXin Li   // CHECK-DCAST: ret
45*67e74705SXin Li   (void)static_cast<B&>(a);
46*67e74705SXin Li }
47*67e74705SXin Li 
48*67e74705SXin Li // CHECK-DCAST-LABEL: define hidden void @_Z4abrrO1A
abrr(A && a)49*67e74705SXin Li void abrr(A &&a) {
50*67e74705SXin Li   // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
51*67e74705SXin Li   // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
52*67e74705SXin Li 
53*67e74705SXin Li   // CHECK-DCAST: [[TRAPBB]]
54*67e74705SXin Li   // CHECK-DCAST-NEXT: call void @llvm.trap()
55*67e74705SXin Li   // CHECK-DCAST-NEXT: unreachable
56*67e74705SXin Li 
57*67e74705SXin Li   // CHECK-DCAST: [[CONTBB]]
58*67e74705SXin Li   // CHECK-DCAST: ret
59*67e74705SXin Li   (void)static_cast<B&&>(a);
60*67e74705SXin Li }
61*67e74705SXin Li 
62*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden void @_Z3vbpPv
vbp(void * p)63*67e74705SXin Li void vbp(void *p) {
64*67e74705SXin Li   // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
65*67e74705SXin Li   // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
66*67e74705SXin Li 
67*67e74705SXin Li   // CHECK-UCAST: [[TRAPBB]]
68*67e74705SXin Li   // CHECK-UCAST-NEXT: call void @llvm.trap()
69*67e74705SXin Li   // CHECK-UCAST-NEXT: unreachable
70*67e74705SXin Li 
71*67e74705SXin Li   // CHECK-UCAST: [[CONTBB]]
72*67e74705SXin Li   // CHECK-UCAST: ret
73*67e74705SXin Li   (void)static_cast<B*>(p);
74*67e74705SXin Li }
75*67e74705SXin Li 
76*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden void @_Z3vbrRc
vbr(char & r)77*67e74705SXin Li void vbr(char &r) {
78*67e74705SXin Li   // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
79*67e74705SXin Li   // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
80*67e74705SXin Li 
81*67e74705SXin Li   // CHECK-UCAST: [[TRAPBB]]
82*67e74705SXin Li   // CHECK-UCAST-NEXT: call void @llvm.trap()
83*67e74705SXin Li   // CHECK-UCAST-NEXT: unreachable
84*67e74705SXin Li 
85*67e74705SXin Li   // CHECK-UCAST: [[CONTBB]]
86*67e74705SXin Li   // CHECK-UCAST: ret
87*67e74705SXin Li   (void)reinterpret_cast<B&>(r);
88*67e74705SXin Li }
89*67e74705SXin Li 
90*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden void @_Z4vbrrOc
vbrr(char && r)91*67e74705SXin Li void vbrr(char &&r) {
92*67e74705SXin Li   // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
93*67e74705SXin Li   // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
94*67e74705SXin Li 
95*67e74705SXin Li   // CHECK-UCAST: [[TRAPBB]]
96*67e74705SXin Li   // CHECK-UCAST-NEXT: call void @llvm.trap()
97*67e74705SXin Li   // CHECK-UCAST-NEXT: unreachable
98*67e74705SXin Li 
99*67e74705SXin Li   // CHECK-UCAST: [[CONTBB]]
100*67e74705SXin Li   // CHECK-UCAST: ret
101*67e74705SXin Li   (void)reinterpret_cast<B&&>(r);
102*67e74705SXin Li }
103*67e74705SXin Li 
104*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden void @_Z3vcpPv
105*67e74705SXin Li // CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3vcpPv
vcp(void * p)106*67e74705SXin Li void vcp(void *p) {
107*67e74705SXin Li   // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
108*67e74705SXin Li   // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
109*67e74705SXin Li   (void)static_cast<C*>(p);
110*67e74705SXin Li }
111*67e74705SXin Li 
112*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden void @_Z3bcpP1B
113*67e74705SXin Li // CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3bcpP1B
bcp(B * p)114*67e74705SXin Li void bcp(B *p) {
115*67e74705SXin Li   // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
116*67e74705SXin Li   // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
117*67e74705SXin Li   (void)(C *)p;
118*67e74705SXin Li }
119*67e74705SXin Li 
120*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden void @_Z8bcp_callP1B
121*67e74705SXin Li // CHECK-UCAST-STRICT-LABEL: define hidden void @_Z8bcp_callP1B
bcp_call(B * p)122*67e74705SXin Li void bcp_call(B *p) {
123*67e74705SXin Li   // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
124*67e74705SXin Li   // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
125*67e74705SXin Li   ((C *)p)->f();
126*67e74705SXin Li }
127*67e74705SXin Li 
128*67e74705SXin Li // CHECK-UCAST-LABEL: define hidden i32 @_Z6a_callP1A
129*67e74705SXin Li // CHECK-UCAST-STRICT-LABEL: define hidden i32 @_Z6a_callP1A
a_call(A * a)130*67e74705SXin Li int a_call(A *a) {
131*67e74705SXin Li   // CHECK-UCAST-NOT: @llvm.type.test
132*67e74705SXin Li   // CHECK-UCAST-STRICT-NOT: @llvm.type.test
133*67e74705SXin Li   return a->i();
134*67e74705SXin Li }
135