Skip to content

Commit 73ddbd3

Browse files
authored
[NFC][CFI] Add tests for different reporting settings (#137225)
1. Trap 2. Abort from runtime 3. Recover from runtime 4. Abort from minimal runtime 5. Recover from minimal runtime They already work as expected.
1 parent f12fb2f commit 73ddbd3

File tree

2 files changed

+320
-0
lines changed

2 files changed

+320
-0
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// RUN: %clang_cc1 -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=TRAP %s
3+
4+
// RUN: %clang_cc1 -fsanitize=cfi-icall -fno-sanitize-trap=cfi-icall -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ABORT %s
5+
6+
// RUN: %clang_cc1 -fsanitize=cfi-icall -fno-sanitize-trap=cfi-icall -fsanitize-recover=cfi-icall -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=RECOVER %s
7+
8+
// RUN: %clang_cc1 -fsanitize=cfi-icall -fno-sanitize-trap=cfi-icall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ABORT_MIN %s
9+
10+
// RUN: %clang_cc1 -fsanitize=cfi-icall -fno-sanitize-trap=cfi-icall -fsanitize-recover=cfi-icall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=RECOVER_MIN %s
11+
12+
// TRAP-LABEL: define hidden void @f(
13+
// TRAP-SAME: ) #[[ATTR0:[0-9]+]] !type [[META6:![0-9]+]] !type [[META7:![0-9]+]] {
14+
// TRAP-NEXT: [[ENTRY:.*:]]
15+
// TRAP-NEXT: ret void
16+
//
17+
// ABORT-LABEL: define hidden void @f(
18+
// ABORT-SAME: ) #[[ATTR0:[0-9]+]] !type [[META6:![0-9]+]] !type [[META7:![0-9]+]] {
19+
// ABORT-NEXT: [[ENTRY:.*:]]
20+
// ABORT-NEXT: ret void
21+
//
22+
// RECOVER-LABEL: define hidden void @f(
23+
// RECOVER-SAME: ) #[[ATTR0:[0-9]+]] !type [[META6:![0-9]+]] !type [[META7:![0-9]+]] {
24+
// RECOVER-NEXT: [[ENTRY:.*:]]
25+
// RECOVER-NEXT: ret void
26+
//
27+
// ABORT_MIN-LABEL: define hidden void @f(
28+
// ABORT_MIN-SAME: ) #[[ATTR0:[0-9]+]] !type [[META6:![0-9]+]] !type [[META7:![0-9]+]] {
29+
// ABORT_MIN-NEXT: [[ENTRY:.*:]]
30+
// ABORT_MIN-NEXT: ret void
31+
//
32+
// RECOVER_MIN-LABEL: define hidden void @f(
33+
// RECOVER_MIN-SAME: ) #[[ATTR0:[0-9]+]] !type [[META6:![0-9]+]] !type [[META7:![0-9]+]] {
34+
// RECOVER_MIN-NEXT: [[ENTRY:.*:]]
35+
// RECOVER_MIN-NEXT: ret void
36+
//
37+
void f() {
38+
}
39+
40+
void xf();
41+
42+
// TRAP-LABEL: define hidden void @g(
43+
// TRAP-SAME: i32 noundef [[B:%.*]]) #[[ATTR0]] !type [[META8:![0-9]+]] !type [[META9:![0-9]+]] {
44+
// TRAP-NEXT: [[ENTRY:.*:]]
45+
// TRAP-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
46+
// TRAP-NEXT: [[FP:%.*]] = alloca ptr, align 8
47+
// TRAP-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
48+
// TRAP-NEXT: [[TMP0:%.*]] = load i32, ptr [[B_ADDR]], align 4
49+
// TRAP-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
50+
// TRAP-NEXT: [[TMP1:%.*]] = zext i1 [[TOBOOL]] to i64
51+
// TRAP-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], ptr @f, ptr @xf
52+
// TRAP-NEXT: store ptr [[COND]], ptr [[FP]], align 8
53+
// TRAP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FP]], align 8
54+
// TRAP-NEXT: [[TMP3:%.*]] = call i1 @llvm.type.test(ptr [[TMP2]], metadata !"_ZTSFvE"), !nosanitize [[META10:![0-9]+]]
55+
// TRAP-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF11:![0-9]+]], !nosanitize [[META10]]
56+
// TRAP: [[TRAP]]:
57+
// TRAP-NEXT: call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !nosanitize [[META10]]
58+
// TRAP-NEXT: unreachable, !nosanitize [[META10]]
59+
// TRAP: [[CONT]]:
60+
// TRAP-NEXT: call void (...) [[TMP2]]()
61+
// TRAP-NEXT: ret void
62+
//
63+
// ABORT-LABEL: define hidden void @g(
64+
// ABORT-SAME: i32 noundef [[B:%.*]]) #[[ATTR0]] !type [[META8:![0-9]+]] !type [[META9:![0-9]+]] {
65+
// ABORT-NEXT: [[ENTRY:.*:]]
66+
// ABORT-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
67+
// ABORT-NEXT: [[FP:%.*]] = alloca ptr, align 8
68+
// ABORT-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
69+
// ABORT-NEXT: [[TMP0:%.*]] = load i32, ptr [[B_ADDR]], align 4
70+
// ABORT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
71+
// ABORT-NEXT: [[TMP1:%.*]] = zext i1 [[TOBOOL]] to i64
72+
// ABORT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], ptr @f, ptr @xf
73+
// ABORT-NEXT: store ptr [[COND]], ptr [[FP]], align 8
74+
// ABORT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FP]], align 8
75+
// ABORT-NEXT: [[TMP3:%.*]] = call i1 @llvm.type.test(ptr [[TMP2]], metadata !"_ZTSFvE"), !nosanitize [[META10:![0-9]+]]
76+
// ABORT-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF11:![0-9]+]], !nosanitize [[META10]]
77+
// ABORT: [[HANDLER_CFI_CHECK_FAIL]]:
78+
// ABORT-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META10]]
79+
// ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(ptr @anon.3d4044d65abdda407a92991f1300ec97.1, i64 [[TMP4]], i64 undef) #[[ATTR4:[0-9]+]], !nosanitize [[META10]]
80+
// ABORT-NEXT: unreachable, !nosanitize [[META10]]
81+
// ABORT: [[CONT]]:
82+
// ABORT-NEXT: call void (...) [[TMP2]]()
83+
// ABORT-NEXT: ret void
84+
//
85+
// RECOVER-LABEL: define hidden void @g(
86+
// RECOVER-SAME: i32 noundef [[B:%.*]]) #[[ATTR0]] !type [[META8:![0-9]+]] !type [[META9:![0-9]+]] {
87+
// RECOVER-NEXT: [[ENTRY:.*:]]
88+
// RECOVER-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
89+
// RECOVER-NEXT: [[FP:%.*]] = alloca ptr, align 8
90+
// RECOVER-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
91+
// RECOVER-NEXT: [[TMP0:%.*]] = load i32, ptr [[B_ADDR]], align 4
92+
// RECOVER-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
93+
// RECOVER-NEXT: [[TMP1:%.*]] = zext i1 [[TOBOOL]] to i64
94+
// RECOVER-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], ptr @f, ptr @xf
95+
// RECOVER-NEXT: store ptr [[COND]], ptr [[FP]], align 8
96+
// RECOVER-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FP]], align 8
97+
// RECOVER-NEXT: [[TMP3:%.*]] = call i1 @llvm.type.test(ptr [[TMP2]], metadata !"_ZTSFvE"), !nosanitize [[META10:![0-9]+]]
98+
// RECOVER-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF11:![0-9]+]], !nosanitize [[META10]]
99+
// RECOVER: [[HANDLER_CFI_CHECK_FAIL]]:
100+
// RECOVER-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META10]]
101+
// RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(ptr @anon.3d4044d65abdda407a92991f1300ec97.1, i64 [[TMP4]], i64 undef) #[[ATTR4:[0-9]+]], !nosanitize [[META10]]
102+
// RECOVER-NEXT: br label %[[CONT]], !nosanitize [[META10]]
103+
// RECOVER: [[CONT]]:
104+
// RECOVER-NEXT: call void (...) [[TMP2]]()
105+
// RECOVER-NEXT: ret void
106+
//
107+
// ABORT_MIN-LABEL: define hidden void @g(
108+
// ABORT_MIN-SAME: i32 noundef [[B:%.*]]) #[[ATTR0]] !type [[META8:![0-9]+]] !type [[META9:![0-9]+]] {
109+
// ABORT_MIN-NEXT: [[ENTRY:.*:]]
110+
// ABORT_MIN-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
111+
// ABORT_MIN-NEXT: [[FP:%.*]] = alloca ptr, align 8
112+
// ABORT_MIN-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
113+
// ABORT_MIN-NEXT: [[TMP0:%.*]] = load i32, ptr [[B_ADDR]], align 4
114+
// ABORT_MIN-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
115+
// ABORT_MIN-NEXT: [[TMP1:%.*]] = zext i1 [[TOBOOL]] to i64
116+
// ABORT_MIN-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], ptr @f, ptr @xf
117+
// ABORT_MIN-NEXT: store ptr [[COND]], ptr [[FP]], align 8
118+
// ABORT_MIN-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FP]], align 8
119+
// ABORT_MIN-NEXT: [[TMP3:%.*]] = call i1 @llvm.type.test(ptr [[TMP2]], metadata !"_ZTSFvE"), !nosanitize [[META10:![0-9]+]]
120+
// ABORT_MIN-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF11:![0-9]+]], !nosanitize [[META10]]
121+
// ABORT_MIN: [[HANDLER_CFI_CHECK_FAIL]]:
122+
// ABORT_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META10]]
123+
// ABORT_MIN-NEXT: unreachable, !nosanitize [[META10]]
124+
// ABORT_MIN: [[CONT]]:
125+
// ABORT_MIN-NEXT: call void (...) [[TMP2]]()
126+
// ABORT_MIN-NEXT: ret void
127+
//
128+
// RECOVER_MIN-LABEL: define hidden void @g(
129+
// RECOVER_MIN-SAME: i32 noundef [[B:%.*]]) #[[ATTR0]] !type [[META8:![0-9]+]] !type [[META9:![0-9]+]] {
130+
// RECOVER_MIN-NEXT: [[ENTRY:.*:]]
131+
// RECOVER_MIN-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
132+
// RECOVER_MIN-NEXT: [[FP:%.*]] = alloca ptr, align 8
133+
// RECOVER_MIN-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
134+
// RECOVER_MIN-NEXT: [[TMP0:%.*]] = load i32, ptr [[B_ADDR]], align 4
135+
// RECOVER_MIN-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
136+
// RECOVER_MIN-NEXT: [[TMP1:%.*]] = zext i1 [[TOBOOL]] to i64
137+
// RECOVER_MIN-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], ptr @f, ptr @xf
138+
// RECOVER_MIN-NEXT: store ptr [[COND]], ptr [[FP]], align 8
139+
// RECOVER_MIN-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FP]], align 8
140+
// RECOVER_MIN-NEXT: [[TMP3:%.*]] = call i1 @llvm.type.test(ptr [[TMP2]], metadata !"_ZTSFvE"), !nosanitize [[META10:![0-9]+]]
141+
// RECOVER_MIN-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF11:![0-9]+]], !nosanitize [[META10]]
142+
// RECOVER_MIN: [[HANDLER_CFI_CHECK_FAIL]]:
143+
// RECOVER_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal() #[[ATTR4:[0-9]+]], !nosanitize [[META10]]
144+
// RECOVER_MIN-NEXT: br label %[[CONT]], !nosanitize [[META10]]
145+
// RECOVER_MIN: [[CONT]]:
146+
// RECOVER_MIN-NEXT: call void (...) [[TMP2]]()
147+
// RECOVER_MIN-NEXT: ret void
148+
//
149+
void g(int b) {
150+
void (*fp)() = b ? f : xf;
151+
fp();
152+
}
153+
//.
154+
// TRAP: [[META6]] = !{i64 0, !"_ZTSFvE"}
155+
// TRAP: [[META7]] = !{i64 0, !"_ZTSFvE.generalized"}
156+
// TRAP: [[META8]] = !{i64 0, !"_ZTSFviE"}
157+
// TRAP: [[META9]] = !{i64 0, !"_ZTSFviE.generalized"}
158+
// TRAP: [[META10]] = !{}
159+
// TRAP: [[PROF11]] = !{!"branch_weights", i32 1048575, i32 1}
160+
//.
161+
// ABORT: [[META6]] = !{i64 0, !"_ZTSFvE"}
162+
// ABORT: [[META7]] = !{i64 0, !"_ZTSFvE.generalized"}
163+
// ABORT: [[META8]] = !{i64 0, !"_ZTSFviE"}
164+
// ABORT: [[META9]] = !{i64 0, !"_ZTSFviE.generalized"}
165+
// ABORT: [[META10]] = !{}
166+
// ABORT: [[PROF11]] = !{!"branch_weights", i32 1048575, i32 1}
167+
//.
168+
// RECOVER: [[META6]] = !{i64 0, !"_ZTSFvE"}
169+
// RECOVER: [[META7]] = !{i64 0, !"_ZTSFvE.generalized"}
170+
// RECOVER: [[META8]] = !{i64 0, !"_ZTSFviE"}
171+
// RECOVER: [[META9]] = !{i64 0, !"_ZTSFviE.generalized"}
172+
// RECOVER: [[META10]] = !{}
173+
// RECOVER: [[PROF11]] = !{!"branch_weights", i32 1048575, i32 1}
174+
//.
175+
// ABORT_MIN: [[META6]] = !{i64 0, !"_ZTSFvE"}
176+
// ABORT_MIN: [[META7]] = !{i64 0, !"_ZTSFvE.generalized"}
177+
// ABORT_MIN: [[META8]] = !{i64 0, !"_ZTSFviE"}
178+
// ABORT_MIN: [[META9]] = !{i64 0, !"_ZTSFviE.generalized"}
179+
// ABORT_MIN: [[META10]] = !{}
180+
// ABORT_MIN: [[PROF11]] = !{!"branch_weights", i32 1048575, i32 1}
181+
//.
182+
// RECOVER_MIN: [[META6]] = !{i64 0, !"_ZTSFvE"}
183+
// RECOVER_MIN: [[META7]] = !{i64 0, !"_ZTSFvE.generalized"}
184+
// RECOVER_MIN: [[META8]] = !{i64 0, !"_ZTSFviE"}
185+
// RECOVER_MIN: [[META9]] = !{i64 0, !"_ZTSFviE.generalized"}
186+
// RECOVER_MIN: [[META10]] = !{}
187+
// RECOVER_MIN: [[PROF11]] = !{!"branch_weights", i32 1048575, i32 1}
188+
//.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// RUN: %clang_cc1 -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=TRAP %s
3+
4+
// RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ABORT %s
5+
6+
// RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -fsanitize-recover=cfi-vcall -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=RECOVER %s
7+
8+
// RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ABORT_MIN %s
9+
10+
// RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -fsanitize-recover=cfi-vcall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=RECOVER_MIN %s
11+
12+
struct S1 {
13+
virtual void f();
14+
};
15+
16+
// TRAP-LABEL: define hidden void @_Z3s1fP2S1(
17+
// TRAP-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
18+
// TRAP-NEXT: [[ENTRY:.*:]]
19+
// TRAP-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
20+
// TRAP-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
21+
// TRAP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
22+
// TRAP-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
23+
// TRAP-NEXT: [[TMP1:%.*]] = call { ptr, i1 } @llvm.type.checked.load(ptr [[VTABLE]], i32 0, metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
24+
// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 1, !nosanitize [[META5]]
25+
// TRAP-NEXT: br i1 [[TMP2]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
26+
// TRAP: [[TRAP]]:
27+
// TRAP-NEXT: call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
28+
// TRAP-NEXT: unreachable, !nosanitize [[META5]]
29+
// TRAP: [[CONT]]:
30+
// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 0, !nosanitize [[META5]]
31+
// TRAP-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
32+
// TRAP-NEXT: ret void
33+
//
34+
// ABORT-LABEL: define hidden void @_Z3s1fP2S1(
35+
// ABORT-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
36+
// ABORT-NEXT: [[ENTRY:.*:]]
37+
// ABORT-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
38+
// ABORT-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
39+
// ABORT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
40+
// ABORT-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
41+
// ABORT-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
42+
// ABORT-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
43+
// ABORT-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
44+
// ABORT: [[HANDLER_CFI_CHECK_FAIL]]:
45+
// ABORT-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64, !nosanitize [[META5]]
46+
// ABORT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i64, !nosanitize [[META5]]
47+
// ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(ptr @anon.00e38160576ab76122d2f8d139d2e390.1, i64 [[TMP3]], i64 [[TMP4]]) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
48+
// ABORT-NEXT: unreachable, !nosanitize [[META5]]
49+
// ABORT: [[CONT]]:
50+
// ABORT-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
51+
// ABORT-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VFN]], align 8
52+
// ABORT-NEXT: call void [[TMP5]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
53+
// ABORT-NEXT: ret void
54+
//
55+
// RECOVER-LABEL: define hidden void @_Z3s1fP2S1(
56+
// RECOVER-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
57+
// RECOVER-NEXT: [[ENTRY:.*:]]
58+
// RECOVER-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
59+
// RECOVER-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
60+
// RECOVER-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
61+
// RECOVER-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
62+
// RECOVER-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
63+
// RECOVER-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
64+
// RECOVER-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
65+
// RECOVER: [[HANDLER_CFI_CHECK_FAIL]]:
66+
// RECOVER-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64, !nosanitize [[META5]]
67+
// RECOVER-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i64, !nosanitize [[META5]]
68+
// RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(ptr @anon.00e38160576ab76122d2f8d139d2e390.1, i64 [[TMP3]], i64 [[TMP4]]) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
69+
// RECOVER-NEXT: br label %[[CONT]], !nosanitize [[META5]]
70+
// RECOVER: [[CONT]]:
71+
// RECOVER-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
72+
// RECOVER-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VFN]], align 8
73+
// RECOVER-NEXT: call void [[TMP5]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
74+
// RECOVER-NEXT: ret void
75+
//
76+
// ABORT_MIN-LABEL: define hidden void @_Z3s1fP2S1(
77+
// ABORT_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
78+
// ABORT_MIN-NEXT: [[ENTRY:.*:]]
79+
// ABORT_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
80+
// ABORT_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
81+
// ABORT_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
82+
// ABORT_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
83+
// ABORT_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
84+
// ABORT_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
85+
// ABORT_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
86+
// ABORT_MIN: [[HANDLER_CFI_CHECK_FAIL]]:
87+
// ABORT_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal_abort() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
88+
// ABORT_MIN-NEXT: unreachable, !nosanitize [[META5]]
89+
// ABORT_MIN: [[CONT]]:
90+
// ABORT_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
91+
// ABORT_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8
92+
// ABORT_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
93+
// ABORT_MIN-NEXT: ret void
94+
//
95+
// RECOVER_MIN-LABEL: define hidden void @_Z3s1fP2S1(
96+
// RECOVER_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
97+
// RECOVER_MIN-NEXT: [[ENTRY:.*:]]
98+
// RECOVER_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
99+
// RECOVER_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
100+
// RECOVER_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
101+
// RECOVER_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
102+
// RECOVER_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
103+
// RECOVER_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
104+
// RECOVER_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
105+
// RECOVER_MIN: [[HANDLER_CFI_CHECK_FAIL]]:
106+
// RECOVER_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
107+
// RECOVER_MIN-NEXT: br label %[[CONT]], !nosanitize [[META5]]
108+
// RECOVER_MIN: [[CONT]]:
109+
// RECOVER_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
110+
// RECOVER_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8
111+
// RECOVER_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
112+
// RECOVER_MIN-NEXT: ret void
113+
//
114+
void s1f(S1 *s1) {
115+
s1->f();
116+
}
117+
//.
118+
// TRAP: [[META5]] = !{}
119+
// TRAP: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
120+
//.
121+
// ABORT: [[META5]] = !{}
122+
// ABORT: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
123+
//.
124+
// RECOVER: [[META5]] = !{}
125+
// RECOVER: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
126+
//.
127+
// ABORT_MIN: [[META5]] = !{}
128+
// ABORT_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
129+
//.
130+
// RECOVER_MIN: [[META5]] = !{}
131+
// RECOVER_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
132+
//.

0 commit comments

Comments
 (0)