// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=cfi-icall -o - %s | FileCheck %s #if !__has_builtin(__builtin_function_start) #error "missing __builtin_function_start" #endif void a(void) {} // CHECK: @e = global ptr no_cfi @_Z1av const void *e = __builtin_function_start(a); constexpr void (*d)() = &a; // CHECK: @f = global ptr no_cfi @_Z1av const void *f = __builtin_function_start(d); void b(void) {} // CHECK: @g = global [2 x ptr] [ptr @_Z1bv, ptr no_cfi @_Z1bv] void *g[] = {(void *)b, __builtin_function_start(b)}; void c(void *p) {} class A { public: void f(); virtual void g(); static void h(); int i() const; int i(int n) const; }; void A::f() {} void A::g() {} void A::h() {} // CHECK: define {{.*}}i32 @_ZNK1A1iEv(ptr {{.*}}%this) int A::i() const { return 0; } // CHECK: define {{.*}}i32 @_ZNK1A1iEi(ptr noundef {{.*}}%this, i32 noundef %n) int A::i(int n) const { return 0; } void h(void) { // CHECK: store ptr no_cfi @_Z1bv, ptr %g void *g = __builtin_function_start(b); // CHECK: call void @_Z1cPv(ptr noundef no_cfi @_Z1av) c(__builtin_function_start(a)); // CHECK: store ptr no_cfi @_ZN1A1fEv, ptr %Af void *Af = __builtin_function_start(&A::f); // CHECK: store ptr no_cfi @_ZN1A1gEv, ptr %Ag void *Ag = __builtin_function_start(&A::g); // CHECK: store ptr no_cfi @_ZN1A1hEv, ptr %Ah void *Ah = __builtin_function_start(&A::h); // CHECK: store ptr no_cfi @_ZNK1A1iEv, ptr %Ai1 void *Ai1 = __builtin_function_start((int(A::*)() const) & A::i); // CHECK: store ptr no_cfi @_ZNK1A1iEi, ptr %Ai2 void *Ai2 = __builtin_function_start((int(A::*)(int) const) & A::i); }