blob: 9fe87111b388f8142384a76bb3e68b64ae070203 [file] [log] [blame]
Peter Collingbourne3afb2662016-04-28 17:09:37 +00001// 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// 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// 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
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
Peter Collingbourne3afb2662016-04-28 17:09:37 +000020// CHECK-DCAST-LABEL: define hidden void @_Z3abpP1A
Peter Collingbourned2926c92015-03-14 02:42:25 +000021void 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
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +000031 (void)static_cast<B*>(a);
Peter Collingbourned2926c92015-03-14 02:42:25 +000032}
33
Peter Collingbourne3afb2662016-04-28 17:09:37 +000034// CHECK-DCAST-LABEL: define hidden void @_Z3abrR1A
Peter Collingbourned2926c92015-03-14 02:42:25 +000035void 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
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +000045 (void)static_cast<B&>(a);
Peter Collingbourned2926c92015-03-14 02:42:25 +000046}
47
Peter Collingbourne3afb2662016-04-28 17:09:37 +000048// CHECK-DCAST-LABEL: define hidden void @_Z4abrrO1A
Peter Collingbourned2926c92015-03-14 02:42:25 +000049void 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
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +000059 (void)static_cast<B&&>(a);
Peter Collingbourned2926c92015-03-14 02:42:25 +000060}
61
Peter Collingbourne3afb2662016-04-28 17:09:37 +000062// CHECK-UCAST-LABEL: define hidden void @_Z3vbpPv
Peter Collingbourned2926c92015-03-14 02:42:25 +000063void 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
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +000073 (void)static_cast<B*>(p);
Peter Collingbourned2926c92015-03-14 02:42:25 +000074}
75
Peter Collingbourne3afb2662016-04-28 17:09:37 +000076// CHECK-UCAST-LABEL: define hidden void @_Z3vbrRc
Peter Collingbourned2926c92015-03-14 02:42:25 +000077void 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
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +000087 (void)reinterpret_cast<B&>(r);
Peter Collingbourned2926c92015-03-14 02:42:25 +000088}
89
Peter Collingbourne3afb2662016-04-28 17:09:37 +000090// CHECK-UCAST-LABEL: define hidden void @_Z4vbrrOc
Peter Collingbourned2926c92015-03-14 02:42:25 +000091void 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
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +0000101 (void)reinterpret_cast<B&&>(r);
Peter Collingbourned2926c92015-03-14 02:42:25 +0000102}
103
Peter Collingbourne3afb2662016-04-28 17:09:37 +0000104// CHECK-UCAST-LABEL: define hidden void @_Z3vcpPv
105// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3vcpPv
Peter Collingbourned2926c92015-03-14 02:42:25 +0000106void 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")
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +0000109 (void)static_cast<C*>(p);
Peter Collingbourned2926c92015-03-14 02:42:25 +0000110}
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000111
Peter Collingbourne3afb2662016-04-28 17:09:37 +0000112// CHECK-UCAST-LABEL: define hidden void @_Z3bcpP1B
113// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3bcpP1B
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000114void 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")
Evgeniy Stepanovf31ea302016-02-03 22:18:55 +0000117 (void)(C *)p;
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000118}
119
Peter Collingbourne3afb2662016-04-28 17:09:37 +0000120// CHECK-UCAST-LABEL: define hidden void @_Z8bcp_callP1B
121// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z8bcp_callP1B
Peter Collingbourneee381ff2015-09-09 00:01:31 +0000122void 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
Peter Collingbourne3afb2662016-04-28 17:09:37 +0000128// CHECK-UCAST-LABEL: define hidden i32 @_Z6a_callP1A
129// CHECK-UCAST-STRICT-LABEL: define hidden i32 @_Z6a_callP1A
Peter Collingbourne574975e2016-01-14 02:49:48 +0000130int a_call(A *a) {
131 // CHECK-UCAST-NOT: @llvm.bitset.test
132 // CHECK-UCAST-STRICT-NOT: @llvm.bitset.test
133 return a->i();
134}