160 lines · cpp
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 52// 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 %s3 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 %s5 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 %s7 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 %s9 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 %s11 12// 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 -fsanitize-handler-preserve-all-regs -emit-llvm -o - %s | FileCheck --check-prefix=PRESERVE_MIN %s13 14// 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 -fsanitize-handler-preserve-all-regs -emit-llvm -o - %s | FileCheck --check-prefix=ABORT_MIN %s15 16 17struct S1 {18 virtual void f();19};20 21// TRAP-LABEL: define hidden void @_Z3s1fP2S1(22// TRAP-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {23// TRAP-NEXT: [[ENTRY:.*:]]24// TRAP-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 825// TRAP-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 826// TRAP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 827// TRAP-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 828// TRAP-NEXT: [[TMP1:%.*]] = call { ptr, i1 } @llvm.type.checked.load(ptr [[VTABLE]], i32 0, metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]29// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 1, !nosanitize [[META5]]30// TRAP-NEXT: br i1 [[TMP2]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]31// TRAP: [[TRAP]]:32// TRAP-NEXT: call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]33// TRAP-NEXT: unreachable, !nosanitize [[META5]]34// TRAP: [[CONT]]:35// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 0, !nosanitize [[META5]]36// TRAP-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])37// TRAP-NEXT: ret void38//39// ABORT-LABEL: define hidden void @_Z3s1fP2S1(40// ABORT-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {41// ABORT-NEXT: [[ENTRY:.*:]]42// ABORT-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 843// ABORT-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 844// ABORT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 845// ABORT-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 846// ABORT-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]47// ABORT-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]48// ABORT-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]49// ABORT: [[HANDLER_CFI_CHECK_FAIL]]:50// ABORT-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64, !nosanitize [[META5]]51// ABORT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i64, !nosanitize [[META5]]52// ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(ptr @anon.00e38160576ab76122d2f8d139d2e390.1, i64 [[TMP3]], i64 [[TMP4]]) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]53// ABORT-NEXT: unreachable, !nosanitize [[META5]]54// ABORT: [[CONT]]:55// ABORT-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 056// ABORT-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VFN]], align 857// ABORT-NEXT: call void [[TMP5]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])58// ABORT-NEXT: ret void59//60// RECOVER-LABEL: define hidden void @_Z3s1fP2S1(61// RECOVER-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {62// RECOVER-NEXT: [[ENTRY:.*:]]63// RECOVER-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 864// RECOVER-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 865// RECOVER-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 866// RECOVER-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 867// RECOVER-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]68// RECOVER-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]69// RECOVER-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]70// RECOVER: [[HANDLER_CFI_CHECK_FAIL]]:71// RECOVER-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64, !nosanitize [[META5]]72// RECOVER-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i64, !nosanitize [[META5]]73// RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(ptr @anon.00e38160576ab76122d2f8d139d2e390.1, i64 [[TMP3]], i64 [[TMP4]]) #[[ATTR3:[0-9]+]], !nosanitize [[META5]]74// RECOVER-NEXT: br label %[[CONT]], !nosanitize [[META5]]75// RECOVER: [[CONT]]:76// RECOVER-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 077// RECOVER-NEXT: [[TMP5:%.*]] = load ptr, ptr [[VFN]], align 878// RECOVER-NEXT: call void [[TMP5]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])79// RECOVER-NEXT: ret void80//81// ABORT_MIN-LABEL: define hidden void @_Z3s1fP2S1(82// ABORT_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {83// ABORT_MIN-NEXT: [[ENTRY:.*:]]84// ABORT_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 885// ABORT_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 886// ABORT_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 887// ABORT_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 888// ABORT_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]89// ABORT_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]90// ABORT_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]91// ABORT_MIN: [[HANDLER_CFI_CHECK_FAIL]]:92// ABORT_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal_abort() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]93// ABORT_MIN-NEXT: unreachable, !nosanitize [[META5]]94// ABORT_MIN: [[CONT]]:95// ABORT_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 096// ABORT_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 897// ABORT_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])98// ABORT_MIN-NEXT: ret void99//100// RECOVER_MIN-LABEL: define hidden void @_Z3s1fP2S1(101// RECOVER_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {102// RECOVER_MIN-NEXT: [[ENTRY:.*:]]103// RECOVER_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8104// RECOVER_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8105// RECOVER_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8106// RECOVER_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8107// RECOVER_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]108// RECOVER_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]109// RECOVER_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]110// RECOVER_MIN: [[HANDLER_CFI_CHECK_FAIL]]:111// RECOVER_MIN-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]112// RECOVER_MIN-NEXT: br label %[[CONT]], !nosanitize [[META5]]113// RECOVER_MIN: [[CONT]]:114// RECOVER_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0115// RECOVER_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8116// RECOVER_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])117// RECOVER_MIN-NEXT: ret void118//119// PRESERVE_MIN-LABEL: define hidden void @_Z3s1fP2S1(120// PRESERVE_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] {121// PRESERVE_MIN-NEXT: [[ENTRY:.*:]]122// PRESERVE_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8123// PRESERVE_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8124// PRESERVE_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8125// PRESERVE_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8126// PRESERVE_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]]127// PRESERVE_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]]128// PRESERVE_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]]129// PRESERVE_MIN: [[HANDLER_CFI_CHECK_FAIL]]:130// PRESERVE_MIN-NEXT: call preserve_allcc void @__ubsan_handle_cfi_check_fail_minimal_preserve() #[[ATTR3:[0-9]+]], !nosanitize [[META5]]131// PRESERVE_MIN-NEXT: br label %[[CONT]], !nosanitize [[META5]]132// PRESERVE_MIN: [[CONT]]:133// PRESERVE_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0134// PRESERVE_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8135// PRESERVE_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]])136// PRESERVE_MIN-NEXT: ret void137//138void s1f(S1 *s1) {139 s1->f();140}141//.142// TRAP: [[META5]] = !{}143// TRAP: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}144//.145// ABORT: [[META5]] = !{}146// ABORT: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}147//.148// RECOVER: [[META5]] = !{}149// RECOVER: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}150//.151// ABORT_MIN: [[META5]] = !{}152// ABORT_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}153//.154// RECOVER_MIN: [[META5]] = !{}155// RECOVER_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}156//.157// PRESERVE_MIN: [[META5]] = !{}158// PRESERVE_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1}159//.160