blob: 05ea8d832790437bae3743f26f0c19bdcfc3e988 [file] [log] [blame]
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --version 5
//
// N.B. although the clang driver defaults to merge, clang_cc1 defaults to non-merge.
// (This is similar to -fsanitize-recover, for which the default is also applied
// at the driver level only.)
// If optimization is disabled, merging is disabled (overrides -fsanitize-merge).
// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux -fsanitize-cfi-cross-dso \
// RUN: -fsanitize=cfi-icall,cfi-nvcall,cfi-vcall,cfi-unrelated-cast,cfi-derived-cast \
// RUN: -fsanitize-trap=cfi-icall,cfi-nvcall \
// RUN: -fsanitize-merge=cfi-icall,cfi-nvcall \
// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=MERGE
// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux -fsanitize-cfi-cross-dso \
// RUN: -fsanitize=cfi-icall,cfi-nvcall,cfi-vcall,cfi-unrelated-cast,cfi-derived-cast \
// RUN: -fsanitize-trap=cfi-icall,cfi-nvcall \
// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=NO-MERGE
// NOMERGE-LABEL: define dso_local void @caller(
// NOMERGE-SAME: ptr noundef [[F:%.*]]) #[[ATTR0:[0-9]+]] !type [[META4:![0-9]+]] !type [[META5:![0-9]+]] !type [[META6:![0-9]+]] {
// NOMERGE-NEXT: [[ENTRY:.*:]]
// NOMERGE-NEXT: [[F_ADDR:%.*]] = alloca ptr, align 8
// NOMERGE-NEXT: store ptr [[F]], ptr [[F_ADDR]], align 8
// NOMERGE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[F_ADDR]], align 8
// NOMERGE-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[TMP0]], metadata !"_ZTSFvvE"), !nosanitize [[META7:![0-9]+]]
// NOMERGE-NEXT: br i1 [[TMP1]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META7]]
// NOMERGE: [[CFI_SLOWPATH]]:
// NOMERGE-NEXT: call void @__cfi_slowpath(i64 9080559750644022485, ptr [[TMP0]]) #[[ATTR7:[0-9]+]], !nosanitize [[META7]]
// NOMERGE-NEXT: br label %[[CFI_CONT]], !nosanitize [[META7]]
// NOMERGE: [[CFI_CONT]]:
// NOMERGE-NEXT: call void [[TMP0]]()
// NOMERGE-NEXT: ret void
void caller(void (*f)(void)) {
f();
}
// MERGE-LABEL: define dso_local void @caller(
// MERGE-SAME: ptr noundef [[F:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !type [[META4:![0-9]+]] !type [[META5:![0-9]+]] !type [[META6:![0-9]+]] {
// MERGE-NEXT: [[ENTRY:.*:]]
// MERGE-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[F]], metadata !"_ZTSFvvE"), !nosanitize [[META7:![0-9]+]]
// MERGE-NEXT: br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META7]]
// MERGE: [[CFI_SLOWPATH]]:
// MERGE-NEXT: tail call void @__cfi_slowpath(i64 9080559750644022485, ptr [[F]]) #[[ATTR5:[0-9]+]], !nosanitize [[META7]]
// MERGE-NEXT: br label %[[CFI_CONT]], !nosanitize [[META7]]
// MERGE: [[CFI_CONT]]:
// MERGE-NEXT: tail call void [[F]]() #[[ATTR5]]
// MERGE-NEXT: ret void
//
//
// MERGE-LABEL: define weak_odr hidden void @__cfi_check_fail(
// MERGE-SAME: ptr noundef [[TMP0:%.*]], ptr noundef [[TMP1:%.*]]) #[[ATTR0]] {
// MERGE-NEXT: [[ENTRY:.*:]]
// MERGE-NEXT: [[DOTNOT:%.*]] = icmp eq ptr [[TMP0]], null, !nosanitize [[META7]]
// MERGE-NEXT: br i1 [[DOTNOT]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META7]]
// MERGE: [[TRAP]]:
// MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR6:[0-9]+]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[CONT]]:
// MERGE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP0]], align 4, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.type.test(ptr [[TMP1]], metadata !"all-vtables"), !nosanitize [[META7]]
// MERGE-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: switch i8 [[TMP2]], label %[[CONT8:.*]] [
// MERGE-NEXT: i8 0, label %[[HANDLER_CFI_CHECK_FAIL:.*]]
// MERGE-NEXT: i8 1, label %[[TRAP]]
// MERGE-NEXT: i8 2, label %[[HANDLER_CFI_CHECK_FAIL4:.*]]
// MERGE-NEXT: i8 3, label %[[HANDLER_CFI_CHECK_FAIL6:.*]]
// MERGE-NEXT: i8 4, label %[[TRAP]]
// MERGE-NEXT: ], !prof [[PROF10:![0-9]+]]
// MERGE: [[HANDLER_CFI_CHECK_FAIL]]:
// MERGE-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP5]], i64 [[TMP6]], i64 [[TMP4]]) #[[ATTR7:[0-9]+]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[HANDLER_CFI_CHECK_FAIL4]]:
// MERGE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP7]], i64 [[TMP8]], i64 [[TMP4]]) #[[ATTR7]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[HANDLER_CFI_CHECK_FAIL6]]:
// MERGE-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP9]], i64 [[TMP10]], i64 [[TMP4]]) #[[ATTR7]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[CONT8]]:
// MERGE-NEXT: ret void, !nosanitize [[META7]]
//
//
// MERGE-LABEL: define weak void @__cfi_check(
// MERGE-SAME: i64 noundef [[TMP0:%.*]], ptr noundef [[TMP1:%.*]], ptr noundef [[TMP2:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] align 4096 {
// MERGE-NEXT: [[ENTRY:.*:]]
// MERGE-NEXT: [[DOTNOT_I:%.*]] = icmp eq ptr [[TMP2]], null, !nosanitize [[META7]]
// MERGE-NEXT: br i1 [[DOTNOT_I]], label %[[TRAP_I:.*]], label %[[CONT_I:.*]], !prof [[PROF9]], !nosanitize [[META7]]
// MERGE: [[TRAP_I]]:
// MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR6]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[CONT_I]]:
// MERGE-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 4, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP4:%.*]] = tail call i1 @llvm.type.test(ptr [[TMP1]], metadata !"all-vtables"), !nosanitize [[META7]]
// MERGE-NEXT: [[TMP5:%.*]] = zext i1 [[TMP4]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: switch i8 [[TMP3]], label %[[__CFI_CHECK_FAIL_EXIT:.*]] [
// MERGE-NEXT: i8 0, label %[[HANDLER_CFI_CHECK_FAIL_I:.*]]
// MERGE-NEXT: i8 1, label %[[TRAP_I]]
// MERGE-NEXT: i8 2, label %[[HANDLER_CFI_CHECK_FAIL4_I:.*]]
// MERGE-NEXT: i8 3, label %[[HANDLER_CFI_CHECK_FAIL6_I:.*]]
// MERGE-NEXT: i8 4, label %[[TRAP_I]]
// MERGE-NEXT: ], !prof [[PROF10]]
// MERGE: [[HANDLER_CFI_CHECK_FAIL_I]]:
// MERGE-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP6]], i64 [[TMP7]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[HANDLER_CFI_CHECK_FAIL4_I]]:
// MERGE-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP8]], i64 [[TMP9]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[HANDLER_CFI_CHECK_FAIL6_I]]:
// MERGE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP10]], i64 [[TMP11]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META7]]
// MERGE-NEXT: unreachable, !nosanitize [[META7]]
// MERGE: [[__CFI_CHECK_FAIL_EXIT]]:
// MERGE-NEXT: ret void
//
//
// NO-MERGE-LABEL: define dso_local void @caller(
// NO-MERGE-SAME: ptr noundef [[F:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !type [[META4:![0-9]+]] !type [[META5:![0-9]+]] !type [[META6:![0-9]+]] {
// NO-MERGE-NEXT: [[ENTRY:.*:]]
// NO-MERGE-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[F]], metadata !"_ZTSFvvE"), !nosanitize [[META7:![0-9]+]]
// NO-MERGE-NEXT: br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META7]]
// NO-MERGE: [[CFI_SLOWPATH]]:
// NO-MERGE-NEXT: tail call void @__cfi_slowpath(i64 9080559750644022485, ptr [[F]]) #[[ATTR5:[0-9]+]], !nosanitize [[META7]]
// NO-MERGE-NEXT: br label %[[CFI_CONT]], !nosanitize [[META7]]
// NO-MERGE: [[CFI_CONT]]:
// NO-MERGE-NEXT: tail call void [[F]]() #[[ATTR5]]
// NO-MERGE-NEXT: ret void
//
//
// NO-MERGE-LABEL: define weak_odr hidden void @__cfi_check_fail(
// NO-MERGE-SAME: ptr noundef [[TMP0:%.*]], ptr noundef [[TMP1:%.*]]) #[[ATTR0]] {
// NO-MERGE-NEXT: [[ENTRY:.*:]]
// NO-MERGE-NEXT: [[DOTNOT:%.*]] = icmp eq ptr [[TMP0]], null, !nosanitize [[META7]]
// NO-MERGE-NEXT: br i1 [[DOTNOT]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META7]]
// NO-MERGE: [[TRAP]]:
// NO-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR6:[0-9]+]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[CONT]]:
// NO-MERGE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP0]], align 4, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.type.test(ptr [[TMP1]], metadata !"all-vtables"), !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: switch i8 [[TMP2]], label %[[CONT10:.*]] [
// NO-MERGE-NEXT: i8 0, label %[[HANDLER_CFI_CHECK_FAIL:.*]]
// NO-MERGE-NEXT: i8 1, label %[[TRAP3:.*]]
// NO-MERGE-NEXT: i8 2, label %[[HANDLER_CFI_CHECK_FAIL5:.*]]
// NO-MERGE-NEXT: i8 3, label %[[HANDLER_CFI_CHECK_FAIL7:.*]]
// NO-MERGE-NEXT: i8 4, label %[[TRAP9:.*]]
// NO-MERGE-NEXT: ], !prof [[PROF10:![0-9]+]]
// NO-MERGE: [[HANDLER_CFI_CHECK_FAIL]]:
// NO-MERGE-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP5]], i64 [[TMP6]], i64 [[TMP4]]) #[[ATTR7:[0-9]+]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[TRAP3]]:
// NO-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[HANDLER_CFI_CHECK_FAIL5]]:
// NO-MERGE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP7]], i64 [[TMP8]], i64 [[TMP4]]) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[HANDLER_CFI_CHECK_FAIL7]]:
// NO-MERGE-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP9]], i64 [[TMP10]], i64 [[TMP4]]) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[TRAP9]]:
// NO-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[CONT10]]:
// NO-MERGE-NEXT: ret void, !nosanitize [[META7]]
//
//
// NO-MERGE-LABEL: define weak void @__cfi_check(
// NO-MERGE-SAME: i64 noundef [[TMP0:%.*]], ptr noundef [[TMP1:%.*]], ptr noundef [[TMP2:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] align 4096 {
// NO-MERGE-NEXT: [[ENTRY:.*:]]
// NO-MERGE-NEXT: [[DOTNOT_I:%.*]] = icmp eq ptr [[TMP2]], null, !nosanitize [[META7]]
// NO-MERGE-NEXT: br i1 [[DOTNOT_I]], label %[[TRAP_I:.*]], label %[[CONT_I:.*]], !prof [[PROF9]], !nosanitize [[META7]]
// NO-MERGE: [[TRAP_I]]:
// NO-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR6]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[CONT_I]]:
// NO-MERGE-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 4, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP4:%.*]] = tail call i1 @llvm.type.test(ptr [[TMP1]], metadata !"all-vtables"), !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP5:%.*]] = zext i1 [[TMP4]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: switch i8 [[TMP3]], label %[[__CFI_CHECK_FAIL_EXIT:.*]] [
// NO-MERGE-NEXT: i8 0, label %[[HANDLER_CFI_CHECK_FAIL_I:.*]]
// NO-MERGE-NEXT: i8 1, label %[[TRAP3_I:.*]]
// NO-MERGE-NEXT: i8 2, label %[[HANDLER_CFI_CHECK_FAIL5_I:.*]]
// NO-MERGE-NEXT: i8 3, label %[[HANDLER_CFI_CHECK_FAIL7_I:.*]]
// NO-MERGE-NEXT: i8 4, label %[[TRAP9_I:.*]]
// NO-MERGE-NEXT: ], !prof [[PROF10]]
// NO-MERGE: [[HANDLER_CFI_CHECK_FAIL_I]]:
// NO-MERGE-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP6]], i64 [[TMP7]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[TRAP3_I]]:
// NO-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[HANDLER_CFI_CHECK_FAIL5_I]]:
// NO-MERGE-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP8]], i64 [[TMP9]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[HANDLER_CFI_CHECK_FAIL7_I]]:
// NO-MERGE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META7]]
// NO-MERGE-NEXT: tail call void @__ubsan_handle_cfi_check_fail_abort(i64 [[TMP10]], i64 [[TMP11]], i64 [[TMP5]]) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[TRAP9_I]]:
// NO-MERGE-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR7]], !nosanitize [[META7]]
// NO-MERGE-NEXT: unreachable, !nosanitize [[META7]]
// NO-MERGE: [[__CFI_CHECK_FAIL_EXIT]]:
// NO-MERGE-NEXT: ret void
// MERGE: [[ATTR5]] = { nounwind }
// MERGE: [[ATTR6]] = { noreturn nounwind }
// NO-MERGE: [[ATTR6]] = { noreturn nounwind }
// NO-MERGE: [[ATTR7]] = { nomerge noreturn nounwind }