
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.
133 lines
8.6 KiB
C++
133 lines
8.6 KiB
C++
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
|
|
// 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
|
|
|
|
// 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
|
|
|
|
// 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
|
|
|
|
// 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
|
|
|
|
// 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
|
|
|
|
struct S1 {
|
|
virtual void f();
|
|
};
|
|
|
|
// TRAP-LABEL: define hidden void @_Z3s1fP2S1(
|
|
// TRAP-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// TRAP-NEXT: [[ENTRY:.*:]]
|
|
// TRAP-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
|
|
// TRAP-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
|
|
// TRAP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
|
|
// TRAP-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
|
|
// TRAP-NEXT: [[TMP1:%.*]] = call { ptr, i1 } @llvm.type.checked.load(ptr [[VTABLE]], i32 0, metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
|
|
// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 1, !nosanitize [[META5]]
|
|
// TRAP-NEXT: br i1 [[TMP2]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
|
|
// TRAP: [[TRAP]]:
|
|
// TRAP-NEXT: call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
|
|
// TRAP-NEXT: unreachable, !nosanitize [[META5]]
|
|
// TRAP: [[CONT]]:
|
|
// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 0, !nosanitize [[META5]]
|
|
// TRAP-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
|
|
// TRAP-NEXT: ret void
|
|
//
|
|
// ABORT-LABEL: define hidden void @_Z3s1fP2S1(
|
|
// ABORT-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// ABORT-NEXT: [[ENTRY:.*:]]
|
|
// ABORT-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
|
|
// ABORT-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
|
|
// ABORT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
|
|
// ABORT-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
|
|
// ABORT-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
|
|
// ABORT-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
|
|
// ABORT-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
|
|
// ABORT: [[HANDLER_CFI_CHECK_FAIL]]:
|
|
// ABORT-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64, !nosanitize [[META5]]
|
|
// ABORT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i64, !nosanitize [[META5]]
|
|
// ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(ptr @anon.00e38160576ab76122d2f8d139d2e390.1, i64 [[TMP3]], i64 [[TMP4]]) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
|
|
// ABORT-NEXT: unreachable, !nosanitize [[META5]]
|
|
// ABORT: [[CONT]]:
|
|
// ABORT-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
|
|
// ABORT-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VFN]], align 8
|
|
// ABORT-NEXT: call void [[TMP5]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
|
|
// ABORT-NEXT: ret void
|
|
//
|
|
// RECOVER-LABEL: define hidden void @_Z3s1fP2S1(
|
|
// RECOVER-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// RECOVER-NEXT: [[ENTRY:.*:]]
|
|
// RECOVER-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
|
|
// RECOVER-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
|
|
// RECOVER-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
|
|
// RECOVER-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
|
|
// RECOVER-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
|
|
// RECOVER-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
|
|
// RECOVER-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
|
|
// RECOVER: [[HANDLER_CFI_CHECK_FAIL]]:
|
|
// RECOVER-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64, !nosanitize [[META5]]
|
|
// RECOVER-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i64, !nosanitize [[META5]]
|
|
// RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(ptr @anon.00e38160576ab76122d2f8d139d2e390.1, i64 [[TMP3]], i64 [[TMP4]]) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
|
|
// RECOVER-NEXT: br label %[[CONT]], !nosanitize [[META5]]
|
|
// RECOVER: [[CONT]]:
|
|
// RECOVER-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
|
|
// RECOVER-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VFN]], align 8
|
|
// RECOVER-NEXT: call void [[TMP5]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
|
|
// RECOVER-NEXT: ret void
|
|
//
|
|
// ABORT_MIN-LABEL: define hidden void @_Z3s1fP2S1(
|
|
// ABORT_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// ABORT_MIN-NEXT: [[ENTRY:.*:]]
|
|
// ABORT_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
|
|
// ABORT_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
|
|
// ABORT_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
|
|
// ABORT_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
|
|
// ABORT_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
|
|
// ABORT_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
|
|
// ABORT_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
|
|
// ABORT_MIN: [[HANDLER_CFI_CHECK_FAIL]]:
|
|
// ABORT_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal_abort() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
|
|
// ABORT_MIN-NEXT: unreachable, !nosanitize [[META5]]
|
|
// ABORT_MIN: [[CONT]]:
|
|
// ABORT_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
|
|
// ABORT_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8
|
|
// ABORT_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
|
|
// ABORT_MIN-NEXT: ret void
|
|
//
|
|
// RECOVER_MIN-LABEL: define hidden void @_Z3s1fP2S1(
|
|
// RECOVER_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// RECOVER_MIN-NEXT: [[ENTRY:.*:]]
|
|
// RECOVER_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8
|
|
// RECOVER_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8
|
|
// RECOVER_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8
|
|
// RECOVER_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8
|
|
// RECOVER_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]
|
|
// RECOVER_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]
|
|
// RECOVER_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]
|
|
// RECOVER_MIN: [[HANDLER_CFI_CHECK_FAIL]]:
|
|
// RECOVER_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]
|
|
// RECOVER_MIN-NEXT: br label %[[CONT]], !nosanitize [[META5]]
|
|
// RECOVER_MIN: [[CONT]]:
|
|
// RECOVER_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0
|
|
// RECOVER_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8
|
|
// RECOVER_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])
|
|
// RECOVER_MIN-NEXT: ret void
|
|
//
|
|
void s1f(S1 *s1) {
|
|
s1->f();
|
|
}
|
|
//.
|
|
// TRAP: [[META5]] = !{}
|
|
// TRAP: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
|
|
//.
|
|
// ABORT: [[META5]] = !{}
|
|
// ABORT: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
|
|
//.
|
|
// RECOVER: [[META5]] = !{}
|
|
// RECOVER: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
|
|
//.
|
|
// ABORT_MIN: [[META5]] = !{}
|
|
// ABORT_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
|
|
//.
|
|
// RECOVER_MIN: [[META5]] = !{}
|
|
// RECOVER_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}
|
|
//.
|