1*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=cfi-icall -o - %s | FileCheck %s
2ec2e26eaSSami Tolvanen
3ec2e26eaSSami Tolvanen #if !__has_builtin(__builtin_function_start)
4ec2e26eaSSami Tolvanen #error "missing __builtin_function_start"
5ec2e26eaSSami Tolvanen #endif
6ec2e26eaSSami Tolvanen
a(void)7ec2e26eaSSami Tolvanen void a(void) {}
8ec2e26eaSSami Tolvanen // CHECK: @e = global i8* bitcast (void ()* no_cfi @_Z1av to i8*)
9ec2e26eaSSami Tolvanen const void *e = __builtin_function_start(a);
10ec2e26eaSSami Tolvanen
11ec2e26eaSSami Tolvanen constexpr void (*d)() = &a;
12ec2e26eaSSami Tolvanen // CHECK: @f = global i8* bitcast (void ()* no_cfi @_Z1av to i8*)
13ec2e26eaSSami Tolvanen const void *f = __builtin_function_start(d);
14ec2e26eaSSami Tolvanen
b(void)15ec2e26eaSSami Tolvanen void b(void) {}
16ec2e26eaSSami Tolvanen // CHECK: @g = global [2 x i8*] [i8* bitcast (void ()* @_Z1bv to i8*), i8* bitcast (void ()* no_cfi @_Z1bv to i8*)]
17ec2e26eaSSami Tolvanen void *g[] = {(void *)b, __builtin_function_start(b)};
18ec2e26eaSSami Tolvanen
c(void * p)19ec2e26eaSSami Tolvanen void c(void *p) {}
20ec2e26eaSSami Tolvanen
21ec2e26eaSSami Tolvanen class A {
22ec2e26eaSSami Tolvanen public:
23ec2e26eaSSami Tolvanen void f();
24ec2e26eaSSami Tolvanen virtual void g();
25ec2e26eaSSami Tolvanen static void h();
26ec2e26eaSSami Tolvanen int i() const;
27ec2e26eaSSami Tolvanen int i(int n) const;
28ec2e26eaSSami Tolvanen };
29ec2e26eaSSami Tolvanen
f()30ec2e26eaSSami Tolvanen void A::f() {}
g()31ec2e26eaSSami Tolvanen void A::g() {}
h()32ec2e26eaSSami Tolvanen void A::h() {}
33ec2e26eaSSami Tolvanen
34ec2e26eaSSami Tolvanen // CHECK: define {{.*}}i32 @_ZNK1A1iEv(%class.A* {{.*}}%this)
i() const35ec2e26eaSSami Tolvanen int A::i() const { return 0; }
36ec2e26eaSSami Tolvanen
371b1c8d83Shyeongyu kim // CHECK: define {{.*}}i32 @_ZNK1A1iEi(%class.A* noundef {{.*}}%this, i32 noundef %n)
i(int n) const38ec2e26eaSSami Tolvanen int A::i(int n) const { return 0; }
39ec2e26eaSSami Tolvanen
h(void)40ec2e26eaSSami Tolvanen void h(void) {
41ec2e26eaSSami Tolvanen // CHECK: store i8* bitcast (void ()* no_cfi @_Z1bv to i8*), i8** %g
42ec2e26eaSSami Tolvanen void *g = __builtin_function_start(b);
431b1c8d83Shyeongyu kim // CHECK: call void @_Z1cPv(i8* noundef bitcast (void ()* no_cfi @_Z1av to i8*))
44ec2e26eaSSami Tolvanen c(__builtin_function_start(a));
45ec2e26eaSSami Tolvanen
46ec2e26eaSSami Tolvanen // CHECK: store i8* bitcast (void (%class.A*)* no_cfi @_ZN1A1fEv to i8*), i8** %Af
47ec2e26eaSSami Tolvanen void *Af = __builtin_function_start(&A::f);
48ec2e26eaSSami Tolvanen // CHECK: store i8* bitcast (void (%class.A*)* no_cfi @_ZN1A1gEv to i8*), i8** %Ag
49ec2e26eaSSami Tolvanen void *Ag = __builtin_function_start(&A::g);
50ec2e26eaSSami Tolvanen // CHECK: store i8* bitcast (void ()* no_cfi @_ZN1A1hEv to i8*), i8** %Ah
51ec2e26eaSSami Tolvanen void *Ah = __builtin_function_start(&A::h);
52ec2e26eaSSami Tolvanen // CHECK: store i8* bitcast (i32 (%class.A*)* no_cfi @_ZNK1A1iEv to i8*), i8** %Ai1
53ec2e26eaSSami Tolvanen void *Ai1 = __builtin_function_start((int(A::*)() const) & A::i);
54ec2e26eaSSami Tolvanen // CHECK: store i8* bitcast (i32 (%class.A*, i32)* no_cfi @_ZNK1A1iEi to i8*), i8** %Ai2
55ec2e26eaSSami Tolvanen void *Ai2 = __builtin_function_start((int(A::*)(int) const) & A::i);
56ec2e26eaSSami Tolvanen }
57