brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · feb7c9c Raw
78 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=cfi-icall -o - %s | FileCheck %s2 3#define CFI_UNCHECKED_CALLEE __attribute__((cfi_unchecked_callee))4 5void unchecked(void) CFI_UNCHECKED_CALLEE {}6 7/// All references to unchecked function with `cfi_unchecked_callee` should have the `cfi_unchecked_callee` wrapper.8// CHECK: @checked = global ptr no_cfi @_Z9uncheckedv9void (*checked)(void) = unchecked;10 11// CHECK: @unchecked2 = global ptr no_cfi @_Z9uncheckedv12void (CFI_UNCHECKED_CALLEE *unchecked2)(void) = unchecked;13 14// CHECK: @checked2 = global ptr no_cfi @_Z9uncheckedv15constexpr void (CFI_UNCHECKED_CALLEE *unchecked_constexpr)(void) = unchecked;16void (*checked2)(void) = unchecked_constexpr;17 18/// Note we still reference the `no_cfi` function rather than the jump table entry.19/// The explicit cast will only silence the warning.20// CHECK: @checked_explicit_cast = global ptr no_cfi @_Z9uncheckedv21void (*checked_explicit_cast)(void) = (void (*)(void))unchecked;22 23// CHECK: @checked_array = global [3 x ptr] [ptr no_cfi @_Z9uncheckedv, ptr no_cfi @_Z9uncheckedv, ptr no_cfi @_Z9uncheckedv]24void (*checked_array[])(void) = {25  unchecked,26  (void (*)(void))unchecked,27  reinterpret_cast<void (*)(void)>(unchecked),28};29 30void func_accepting_checked(void (*p)(void)) {}31 32// CHECK-LABEL: _Z9InvokeCFIv33void InvokeCFI() {34  // CHECK: %0 = load ptr, ptr @checked, align 835  // CHECK: %1 = call i1 @llvm.type.test(ptr %0, metadata !"_ZTSFvvE")36  checked();37}38 39// CHECK-LABEL: _Z11InvokeNoCFIv40void InvokeNoCFI() {41  // CHECK:  %0 = load ptr, ptr @unchecked2, align 842  // CHECK:  call void %0()43  unchecked2();44}45 46struct A {47  void unchecked_method() CFI_UNCHECKED_CALLEE {}48  virtual void unchecked_virtual_method() CFI_UNCHECKED_CALLEE {}49  static void unchecked_static_method() CFI_UNCHECKED_CALLEE {}50  int unchecked_const_method() const CFI_UNCHECKED_CALLEE { return 0; }51  int unchecked_const_method_int_arg(int n) const CFI_UNCHECKED_CALLEE { return 0; }52};53 54void h(void) {55  // CHECK: store ptr no_cfi @_Z9uncheckedv, ptr %unchecked_local56  void (*unchecked_local)(void) = unchecked;57 58  // CHECK: call void @_Z22func_accepting_checkedPFvvE(ptr noundef no_cfi @_Z9uncheckedv)59  func_accepting_checked(unchecked);60 61  // CHECK:      [[B:%.*]] = load ptr, ptr @checked62  // CHECK-NEXT: call void @_Z22func_accepting_checkedPFvvE(ptr noundef [[B]]) 63  func_accepting_checked(checked);64 65  // CHECK: store { i64, i64 } { i64 ptrtoint (ptr no_cfi @_ZN1A16unchecked_methodEv to i64), i64 0 }, ptr %A166  auto A1 = &A::unchecked_method;67  /// Storing unchecked virtual function pointer stores an offset instead. This is part of the68  /// normal Itanium C++ ABI, but let's make sure we don't change anything.69  // CHECK: store { i64, i64 } { i64 1, i64 0 }, ptr %A270  auto A2 = &A::unchecked_virtual_method;71  // CHECK: store ptr no_cfi @_ZN1A23unchecked_static_methodEv, ptr %A372  auto A3 = &A::unchecked_static_method;73  // CHECK: store { i64, i64 } { i64 ptrtoint (ptr no_cfi @_ZNK1A22unchecked_const_methodEv to i64), i64 0 }, ptr %A474  auto A4 = (int(CFI_UNCHECKED_CALLEE A::*)() const)(&A::unchecked_const_method);75  // CHECK: store { i64, i64 } { i64 ptrtoint (ptr no_cfi @_ZNK1A30unchecked_const_method_int_argEi to i64), i64 0 }, ptr %A576  auto A5 = (int(CFI_UNCHECKED_CALLEE A::*)(int) const)(&A::unchecked_const_method_int_arg);77}78