88/// Must emit __kcfi_typeid symbols for address-taken function declarations
99// CHECK: module asm ".weak __kcfi_typeid_[[F4:[a-zA-Z0-9_]+]]"
1010// CHECK: module asm ".set __kcfi_typeid_[[F4]], [[#%d,HASH:]]"
11+ // CHECK: module asm ".weak __kcfi_typeid_[[F4_ARG:[a-zA-Z0-9_]+]]"
12+ // CHECK: module asm ".set __kcfi_typeid_[[F4_ARG]], [[#%d,ARG_HASH:]]"
13+
1114/// Must not __kcfi_typeid symbols for non-address-taken declarations
1215// CHECK-NOT: module asm ".weak __kcfi_typeid_{{f6|_Z2f6v}}"
1316
1417// C: @ifunc1 = ifunc i32 (i32), ptr @resolver1
1518// C: @ifunc2 = ifunc i64 (i64), ptr @resolver2
1619typedef int (* fn_t )(void );
20+ typedef int (* fn_u_t )(unsigned int );
1721
18- // CHECK: define dso_local{{.*}} i32 @{{f1|_Z2f1v}}(){{.*}} !kcfi_type ![[#TYPE:]]
19- int f1 (void ) { return 0 ; }
22+ int f1 (void );
2023
21- // CHECK: define dso_local{{.*}} i32 @{{f2|_Z2f2v}}(){{.*}} !kcfi_type ![[#TYPE2:]]
22- unsigned int f2 (void ) { return 2 ; }
24+ unsigned int f2 (void );
25+
26+ static int f3 (void );
27+
28+ extern int f4 (void );
29+ extern int f4_arg (unsigned int );
2330
2431// CHECK-LABEL: define dso_local{{.*}} i32 @{{__call|_Z6__callPFivE}}(ptr{{.*}} %f)
2532int __call (fn_t f ) __attribute__((__no_sanitize__ ("kcfi" ))) {
2633 // CHECK-NOT: call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"
2734 return f ();
2835}
2936
30- // CHECK: define dso_local{{.*}} i32 @{{call|_Z4callPFivE}}(ptr{{.*}} %f){{.*}}
37+ // CHECK-LABEL : define dso_local{{.*}} i32 @{{call|_Z4callPFivE}}(ptr{{.*}} %f)
3138int call (fn_t f ) {
3239 // CHECK: call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#HASH]]) ]
3340 return f ();
3441}
3542
36- // CHECK-DAG: define internal{{.*}} i32 @{{f3|_ZL2f3v}}(){{.*}} !kcfi_type ![[#TYPE]]
43+ // CHECK-LABEL: define dso_local{{.*}} i32 @{{call_with_arg|_Z13call_with_argPFijE}}(ptr{{.*}} %f)
44+ int call_with_arg (fn_u_t f ) {
45+ // CHECK: call{{.*}} i32 %0(i32 {{.*}}) [ "kcfi"(i32 [[#ARG_HASH]]) ]
46+ return f (42 );
47+ }
48+
49+ static int f5 (void );
50+
51+ extern int f6 (void );
52+
53+ int test (void ) {
54+ return call (f1 ) +
55+ __call ((fn_t )f2 ) +
56+ call (f3 ) +
57+ call (f4 ) +
58+ call_with_arg (f4_arg ) +
59+ f5 () +
60+ f6 ();
61+ }
62+
63+ // CHECK-LABEL: define dso_local{{.*}} i32 @{{f1|_Z2f1v}}(){{.*}} !kcfi_type ![[#TYPE:]]
64+ int f1 (void ) { return 0 ; }
65+
66+ // CHECK-LABEL: define dso_local{{.*}} i32 @{{f2|_Z2f2v}}(){{.*}} !kcfi_type ![[#TYPE2:]]
67+ unsigned int f2 (void ) { return 2 ; }
68+
69+ // CHECK: define internal{{.*}} i32 @{{f3|_ZL2f3v}}(){{.*}} !kcfi_type ![[#TYPE]]
3770static int f3 (void ) { return 1 ; }
3871
39- // CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @[[F4]]()
40- extern int f4 (void );
72+ // CHECK-LABEL: declare !kcfi_type
73+ // CHECK-SAME: ![[#TYPE]]{{.*}} i32 @[[F4]]
74+ // CHECK-LABEL: declare !kcfi_type
75+ // CHECK-SAME: ![[#ARG_TYPE:]]{{.*}} i32 @[[F4_ARG]]
4176
4277/// Must not emit !kcfi_type for non-address-taken local functions
4378// CHECK: define internal{{.*}} i32 @{{f5|_ZL2f5v}}()
4479// CHECK-NOT: !kcfi_type
4580// CHECK-SAME: {
4681static int f5 (void ) { return 2 ; }
4782
48- // CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @{{f6|_Z2f6v}}()
49- extern int f6 (void );
83+ // CHECK: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @{{f6|_Z2f6v}}()
5084
5185#ifndef __cplusplus
5286// C: define internal ptr @resolver1() #[[#]] !kcfi_type ![[#]] {
@@ -58,30 +92,26 @@ static void *resolver2(void) { return 0; }
5892long ifunc2 (long ) __attribute__((ifunc ("resolver2" )));
5993#endif
6094
61- int test (void ) {
62- return call (f1 ) +
63- __call ((fn_t )f2 ) +
64- call (f3 ) +
65- call (f4 ) +
66- f5 () +
67- f6 ();
68- }
69-
7095#ifdef __cplusplus
7196struct A {
72- // MEMBER-DAG: define{{.*}} void @_ZN1A1fEv(ptr{{.*}} %this){{.*}} !kcfi_type ![[#TYPE3:]]
7397 void f () {}
7498};
7599
76100void test_member_call (void ) {
77101 void (A ::* p )() = & A ::f ;
78- // MEMBER-DAG : call void %[[#]](ptr{{.*}} [ "kcfi"(i32 [[#%d,HASH3:]]) ]
102+ // MEMBER: call void %[[#]](ptr{{.*}} [ "kcfi"(i32 [[#%d,HASH3:]]) ]
79103 (A ().* p )();
80104}
105+
106+ // MEMBER: define{{.*}} void @_ZN1A1fEv(ptr{{.*}} %this){{.*}} !kcfi_type ![[#TYPE3:]]
81107#endif
82108
83- // CHECK-DAG: ![[#]] = !{i32 4, !"kcfi", i32 1}
84- // OFFSET-DAG: ![[#]] = !{i32 4, !"kcfi-offset", i32 3}
85- // CHECK-DAG: ![[#TYPE]] = !{i32 [[#HASH]]}
86- // CHECK-DAG: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]}
87- // MEMBER-DAG: ![[#TYPE3]] = !{i32 [[#HASH3]]}
109+ // CHECK: ![[#]] = !{i32 4, !"kcfi", i32 1}
110+ //
111+ // OFFSET: ![[#]] = !{i32 4, !"kcfi-offset", i32 3}
112+ //
113+ // CHECK: ![[#TYPE]] = !{i32 [[#HASH]]}
114+ // CHECK: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]}
115+ // CHECK: ![[#ARG_TYPE]] = !{i32 [[#ARG_HASH]]}
116+ //
117+ // MEMBER: ![[#TYPE3]] = !{i32 [[#HASH3]]}
0 commit comments