CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
78 lines
3.3 KiB
C++
78 lines
3.3 KiB
C++
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=cfi-icall -o - %s | FileCheck %s
|
|
|
|
#define CFI_UNCHECKED_CALLEE __attribute__((cfi_unchecked_callee))
|
|
|
|
void unchecked(void) CFI_UNCHECKED_CALLEE {}
|
|
|
|
/// All references to unchecked function with `cfi_unchecked_callee` should have the `cfi_unchecked_callee` wrapper.
|
|
// CHECK: @checked = global ptr no_cfi @_Z9uncheckedv
|
|
void (*checked)(void) = unchecked;
|
|
|
|
// CHECK: @unchecked2 = global ptr no_cfi @_Z9uncheckedv
|
|
void (CFI_UNCHECKED_CALLEE *unchecked2)(void) = unchecked;
|
|
|
|
// CHECK: @checked2 = global ptr no_cfi @_Z9uncheckedv
|
|
constexpr void (CFI_UNCHECKED_CALLEE *unchecked_constexpr)(void) = unchecked;
|
|
void (*checked2)(void) = unchecked_constexpr;
|
|
|
|
/// Note we still reference the `no_cfi` function rather than the jump table entry.
|
|
/// The explicit cast will only silence the warning.
|
|
// CHECK: @checked_explicit_cast = global ptr no_cfi @_Z9uncheckedv
|
|
void (*checked_explicit_cast)(void) = (void (*)(void))unchecked;
|
|
|
|
// CHECK: @checked_array = global [3 x ptr] [ptr no_cfi @_Z9uncheckedv, ptr no_cfi @_Z9uncheckedv, ptr no_cfi @_Z9uncheckedv]
|
|
void (*checked_array[])(void) = {
|
|
unchecked,
|
|
(void (*)(void))unchecked,
|
|
reinterpret_cast<void (*)(void)>(unchecked),
|
|
};
|
|
|
|
void func_accepting_checked(void (*p)(void)) {}
|
|
|
|
// CHECK-LABEL: _Z9InvokeCFIv
|
|
void InvokeCFI() {
|
|
// CHECK: %0 = load ptr, ptr @checked, align 8
|
|
// CHECK: %1 = call i1 @llvm.type.test(ptr %0, metadata !"_ZTSFvvE")
|
|
checked();
|
|
}
|
|
|
|
// CHECK-LABEL: _Z11InvokeNoCFIv
|
|
void InvokeNoCFI() {
|
|
// CHECK: %0 = load ptr, ptr @unchecked2, align 8
|
|
// CHECK: call void %0()
|
|
unchecked2();
|
|
}
|
|
|
|
struct A {
|
|
void unchecked_method() CFI_UNCHECKED_CALLEE {}
|
|
virtual void unchecked_virtual_method() CFI_UNCHECKED_CALLEE {}
|
|
static void unchecked_static_method() CFI_UNCHECKED_CALLEE {}
|
|
int unchecked_const_method() const CFI_UNCHECKED_CALLEE { return 0; }
|
|
int unchecked_const_method_int_arg(int n) const CFI_UNCHECKED_CALLEE { return 0; }
|
|
};
|
|
|
|
void h(void) {
|
|
// CHECK: store ptr no_cfi @_Z9uncheckedv, ptr %unchecked_local
|
|
void (*unchecked_local)(void) = unchecked;
|
|
|
|
// CHECK: call void @_Z22func_accepting_checkedPFvvE(ptr noundef no_cfi @_Z9uncheckedv)
|
|
func_accepting_checked(unchecked);
|
|
|
|
// CHECK: [[B:%.*]] = load ptr, ptr @checked
|
|
// CHECK-NEXT: call void @_Z22func_accepting_checkedPFvvE(ptr noundef [[B]])
|
|
func_accepting_checked(checked);
|
|
|
|
// CHECK: store { i64, i64 } { i64 ptrtoint (ptr no_cfi @_ZN1A16unchecked_methodEv to i64), i64 0 }, ptr %A1
|
|
auto A1 = &A::unchecked_method;
|
|
/// Storing unchecked virtual function pointer stores an offset instead. This is part of the
|
|
/// normal Itanium C++ ABI, but let's make sure we don't change anything.
|
|
// CHECK: store { i64, i64 } { i64 1, i64 0 }, ptr %A2
|
|
auto A2 = &A::unchecked_virtual_method;
|
|
// CHECK: store ptr no_cfi @_ZN1A23unchecked_static_methodEv, ptr %A3
|
|
auto A3 = &A::unchecked_static_method;
|
|
// CHECK: store { i64, i64 } { i64 ptrtoint (ptr no_cfi @_ZNK1A22unchecked_const_methodEv to i64), i64 0 }, ptr %A4
|
|
auto A4 = (int(CFI_UNCHECKED_CALLEE A::*)() const)(&A::unchecked_const_method);
|
|
// CHECK: store { i64, i64 } { i64 ptrtoint (ptr no_cfi @_ZNK1A30unchecked_const_method_int_argEi to i64), i64 0 }, ptr %A5
|
|
auto A5 = (int(CFI_UNCHECKED_CALLEE A::*)(int) const)(&A::unchecked_const_method_int_arg);
|
|
}
|