[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / ptrauth-function-type-discriminator.c
blob0952c1abf6c07777bcefcad9d2dcb5e5f876669f
1 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \
2 // RUN: -disable-llvm-passes -emit-llvm %s -o- | FileCheck --check-prefixes=CHECK,CHECKC %s
3 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \
4 // RUN: -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck --check-prefix=CHECK %s
5 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast
6 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
7 // RUN: -emit-llvm -x ast -o - %t.ast | FileCheck --check-prefixes=CHECK,CHECKC %s
9 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
10 // RUN: -disable-llvm-passes -emit-llvm %s -o- | FileCheck --check-prefixes=CHECK,CHECKC %s
11 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
12 // RUN: -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck --check-prefix=CHECK %s
13 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast
14 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
15 // RUN: -emit-llvm -x ast -o - %t.ast | FileCheck --check-prefixes=CHECK,CHECKC %s
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
21 void f(void);
22 void f2(int);
23 void (*fnptr)(void);
24 void *opaque;
25 unsigned long uintptr;
27 // CHECK: @test_constant_null = global ptr null
28 void (*test_constant_null)(int) = 0;
30 // CHECK: @test_constant_cast = global ptr ptrauth (ptr @f, i32 0, i64 2712)
31 void (*test_constant_cast)(int) = (void (*)(int))f;
33 #ifndef __cplusplus
34 // CHECKC: @enum_func_ptr = global ptr ptrauth (ptr @enum_func, i32 0, i64 2712)
35 enum Enum0;
36 void enum_func(enum Enum0);
37 void (*enum_func_ptr)(enum Enum0) = enum_func;
38 #endif
40 // CHECK: @test_opaque = global ptr ptrauth (ptr @f, i32 0)
41 void *test_opaque =
42 #ifdef __cplusplus
43 (void *)
44 #endif
45 (void (*)(int))(double (*)(double))f;
47 // CHECK: @test_intptr_t = global i64 ptrtoint (ptr ptrauth (ptr @f, i32 0) to i64)
48 unsigned long test_intptr_t = (unsigned long)f;
50 // CHECK: @test_through_long = global ptr ptrauth (ptr @f, i32 0, i64 2712)
51 void (*test_through_long)(int) = (void (*)(int))(long)f;
53 // CHECK: @test_to_long = global i64 ptrtoint (ptr ptrauth (ptr @f, i32 0) to i64)
54 long test_to_long = (long)(double (*)())f;
56 extern void external_function(void);
57 // CHECK: @fptr1 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983)
58 void (*fptr1)(void) = external_function;
59 // CHECK: @fptr2 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983)
60 void (*fptr2)(void) = &external_function;
62 // CHECK: @fptr3 = global ptr ptrauth (ptr @external_function, i32 2, i64 26)
63 void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26);
65 // CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4)
66 void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26));
68 // CHECK-LABEL: define{{.*}} void @test_call()
69 void test_call() {
70 // CHECK: [[T0:%.*]] = load ptr, ptr @fnptr,
71 // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i32 0, i64 18983) ]
72 fnptr();
75 // CHECK-LABEL: define{{.*}} ptr @test_function_pointer()
76 // CHECK: ret ptr ptrauth (ptr @external_function, i32 0, i64 18983)
77 void (*test_function_pointer())(void) {
78 return external_function;
81 struct InitiallyIncomplete;
82 extern struct InitiallyIncomplete returns_initially_incomplete(void);
83 // CHECK-LABEL: define{{.*}} void @use_while_incomplete()
84 void use_while_incomplete() {
85 // CHECK: [[VAR:%.*]] = alloca ptr,
86 // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
87 struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete;
89 struct InitiallyIncomplete { int x; };
90 // CHECK-LABEL: define{{.*}} void @use_while_complete()
91 void use_while_complete() {
92 // CHECK: [[VAR:%.*]] = alloca ptr,
93 // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
94 // CHECK-NEXT: ret void
95 struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete;
98 #ifndef __cplusplus
100 void knr(param)
101 int param;
104 // CHECKC-LABEL: define{{.*}} void @test_knr
105 void test_knr() {
106 void (*p)() = knr;
107 p(0);
109 // CHECKC: [[P:%.*]] = alloca ptr
110 // CHECKC: store ptr ptrauth (ptr @knr, i32 0, i64 18983), ptr [[P]]
111 // CHECKC: [[LOAD:%.*]] = load ptr, ptr [[P]]
112 // CHECKC: call void [[LOAD]](i32 noundef 0) [ "ptrauth"(i32 0, i64 18983) ]
115 // CHECKC-LABEL: define{{.*}} void @test_redeclaration
116 void test_redeclaration() {
117 void redecl();
118 void (*ptr)() = redecl;
119 void redecl(int);
120 void (*ptr2)(int) = redecl;
121 ptr();
122 ptr2(0);
124 // CHECKC: store ptr ptrauth (ptr @redecl, i32 0, i64 18983), ptr %ptr
125 // CHECKC: store ptr ptrauth (ptr @redecl, i32 0, i64 2712), ptr %ptr2
126 // CHECKC: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ]
127 // CHECKC: call void {{.*}}(i32 noundef 0) [ "ptrauth"(i32 0, i64 2712) ]
130 void knr2(param)
131 int param;
134 // CHECKC-LABEL: define{{.*}} void @test_redecl_knr
135 void test_redecl_knr() {
136 void (*p)() = knr2;
137 p();
139 // CHECKC: store ptr ptrauth (ptr @knr2, i32 0, i64 18983)
140 // CHECKC: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ]
142 void knr2(int);
144 void (*p2)(int) = knr2;
145 p2(0);
147 // CHECKC: store ptr ptrauth (ptr @knr2, i32 0, i64 2712)
148 // CHECKC: call void {{.*}}(i32 noundef 0) [ "ptrauth"(i32 0, i64 2712) ]
151 #endif
153 #ifdef __cplusplus
155 #endif