1 // RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s -fexperimental-new-constant-interpreter
3 #if __has_feature(ptrauth_intrinsics)
4 #warning Pointer authentication enabled!
5 // expected-warning@-1 {{Pointer authentication enabled!}}
9 #define VALID_CODE_KEY 0
10 #define VALID_DATA_KEY 2
11 #define INVALID_KEY 200
13 #error Provide these constants if you port this test
16 #define NULL ((void*) 0)
17 struct A
{ int x
; } mismatched_type
;
22 void test_strip(int *dp
, int (*fp
)(int)) {
23 __builtin_ptrauth_strip(dp
); // expected-error {{too few arguments}}
24 __builtin_ptrauth_strip(dp
, VALID_DATA_KEY
, dp
); // expected-error {{too many arguments}}
25 (void) __builtin_ptrauth_strip(NULL
, VALID_DATA_KEY
); // no warning
27 __builtin_ptrauth_strip(mismatched_type
, VALID_DATA_KEY
); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
28 __builtin_ptrauth_strip(dp
, mismatched_type
); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
30 int *dr
= __builtin_ptrauth_strip(dp
, VALID_DATA_KEY
);
31 dr
= __builtin_ptrauth_strip(dp
, INVALID_KEY
); // expected-error {{does not identify a valid pointer authentication key for the current target}}
33 int (*fr
)(int) = __builtin_ptrauth_strip(fp
, VALID_CODE_KEY
);
34 fr
= __builtin_ptrauth_strip(fp
, INVALID_KEY
); // expected-error {{does not identify a valid pointer authentication key for the current target}}
36 float *mismatch
= __builtin_ptrauth_strip(dp
, VALID_DATA_KEY
); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
39 void test_blend_discriminator(int *dp
, int (*fp
)(int), int value
) {
40 __builtin_ptrauth_blend_discriminator(dp
); // expected-error {{too few arguments}}
41 __builtin_ptrauth_blend_discriminator(dp
, dp
, dp
); // expected-error {{too many arguments}}
42 (void) __builtin_ptrauth_blend_discriminator(dp
, value
); // no warning
44 __builtin_ptrauth_blend_discriminator(mismatched_type
, value
); // expected-error {{blended pointer must have pointer type; type here is 'struct A'}}
45 __builtin_ptrauth_blend_discriminator(dp
, mismatched_type
); // expected-error {{blended integer must have integer type; type here is 'struct A'}}
47 float *mismatch
= __builtin_ptrauth_blend_discriminator(dp
, value
); // expected-error {{incompatible integer to pointer conversion initializing 'float *' with an expression of type}}
50 void test_string_discriminator(const char *str
) {
51 __builtin_ptrauth_string_discriminator(); // expected-error {{too few arguments}}
52 __builtin_ptrauth_string_discriminator(str
, str
); // expected-error {{too many arguments}}
53 (void) __builtin_ptrauth_string_discriminator("test string"); // no warning
55 __builtin_ptrauth_string_discriminator(str
); // expected-error {{argument must be a string literal}}
56 __builtin_ptrauth_string_discriminator(L
"wide test"); // expected-error {{argument must be a string literal}} expected-warning {{incompatible pointer types passing 'int[10]' to parameter of type 'const char *'}}
58 void *mismatch
= __builtin_ptrauth_string_discriminator("test string"); // expected-error {{incompatible integer to pointer conversion initializing 'void *' with an expression of type 'unsigned long'}}
62 void test_sign_unauthenticated(int *dp
, int (*fp
)(int)) {
63 __builtin_ptrauth_sign_unauthenticated(dp
, VALID_DATA_KEY
); // expected-error {{too few arguments}}
64 __builtin_ptrauth_sign_unauthenticated(dp
, VALID_DATA_KEY
, dp
, dp
); // expected-error {{too many arguments}}
66 __builtin_ptrauth_sign_unauthenticated(mismatched_type
, VALID_DATA_KEY
, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
67 __builtin_ptrauth_sign_unauthenticated(dp
, mismatched_type
, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
68 __builtin_ptrauth_sign_unauthenticated(dp
, VALID_DATA_KEY
, mismatched_type
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
70 (void) __builtin_ptrauth_sign_unauthenticated(NULL
, VALID_DATA_KEY
, 0); // expected-warning {{signing a null pointer will yield a non-null pointer}}
72 int *dr
= __builtin_ptrauth_sign_unauthenticated(dp
, VALID_DATA_KEY
, 0);
73 dr
= __builtin_ptrauth_sign_unauthenticated(dp
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
75 int (*fr
)(int) = __builtin_ptrauth_sign_unauthenticated(fp
, VALID_CODE_KEY
, 0);
76 fr
= __builtin_ptrauth_sign_unauthenticated(fp
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
78 float *mismatch
= __builtin_ptrauth_sign_unauthenticated(dp
, VALID_DATA_KEY
, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
81 void test_auth(int *dp
, int (*fp
)(int)) {
82 __builtin_ptrauth_auth(dp
, VALID_DATA_KEY
); // expected-error {{too few arguments}}
83 __builtin_ptrauth_auth(dp
, VALID_DATA_KEY
, dp
, dp
); // expected-error {{too many arguments}}
85 __builtin_ptrauth_auth(mismatched_type
, VALID_DATA_KEY
, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
86 __builtin_ptrauth_auth(dp
, mismatched_type
, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
87 __builtin_ptrauth_auth(dp
, VALID_DATA_KEY
, mismatched_type
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
89 (void) __builtin_ptrauth_auth(NULL
, VALID_DATA_KEY
, 0); // expected-warning {{authenticating a null pointer will almost certainly trap}}
91 int *dr
= __builtin_ptrauth_auth(dp
, VALID_DATA_KEY
, 0);
92 dr
= __builtin_ptrauth_auth(dp
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
94 int (*fr
)(int) = __builtin_ptrauth_auth(fp
, VALID_CODE_KEY
, 0);
95 fr
= __builtin_ptrauth_auth(fp
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
97 float *mismatch
= __builtin_ptrauth_auth(dp
, VALID_DATA_KEY
, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
100 void test_auth_and_resign(int *dp
, int (*fp
)(int)) {
101 __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, 0, VALID_DATA_KEY
); // expected-error {{too few arguments}}
102 __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, dp
, VALID_DATA_KEY
, dp
, 0); // expected-error {{too many arguments}}
104 __builtin_ptrauth_auth_and_resign(mismatched_type
, VALID_DATA_KEY
, 0, VALID_DATA_KEY
, dp
); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
105 __builtin_ptrauth_auth_and_resign(dp
, mismatched_type
, 0, VALID_DATA_KEY
, dp
); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
106 __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, mismatched_type
, VALID_DATA_KEY
, dp
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
107 __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, 0, mismatched_type
, dp
); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
108 __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, 0, VALID_DATA_KEY
, mismatched_type
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
110 (void) __builtin_ptrauth_auth_and_resign(NULL
, VALID_DATA_KEY
, 0, VALID_DATA_KEY
, dp
); // expected-warning {{authenticating a null pointer will almost certainly trap}}
112 int *dr
= __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, 0, VALID_DATA_KEY
, dp
);
113 dr
= __builtin_ptrauth_auth_and_resign(dp
, INVALID_KEY
, 0, VALID_DATA_KEY
, dp
); // expected-error {{does not identify a valid pointer authentication key for the current target}}
114 dr
= __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, 0, INVALID_KEY
, dp
); // expected-error {{does not identify a valid pointer authentication key for the current target}}
116 int (*fr
)(int) = __builtin_ptrauth_auth_and_resign(fp
, VALID_CODE_KEY
, 0, VALID_CODE_KEY
, dp
);
117 fr
= __builtin_ptrauth_auth_and_resign(fp
, INVALID_KEY
, 0, VALID_CODE_KEY
, dp
); // expected-error {{does not identify a valid pointer authentication key for the current target}}
118 fr
= __builtin_ptrauth_auth_and_resign(fp
, VALID_CODE_KEY
, 0, INVALID_KEY
, dp
); // expected-error {{does not identify a valid pointer authentication key for the current target}}
120 float *mismatch
= __builtin_ptrauth_auth_and_resign(dp
, VALID_DATA_KEY
, 0, VALID_DATA_KEY
, dp
); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
123 void test_sign_generic_data(int *dp
) {
124 __builtin_ptrauth_sign_generic_data(dp
); // expected-error {{too few arguments}}
125 __builtin_ptrauth_sign_generic_data(dp
, 0, 0); // expected-error {{too many arguments}}
127 __builtin_ptrauth_sign_generic_data(mismatched_type
, 0); // expected-error {{signed value must have pointer or integer type; type here is 'struct A'}}
128 __builtin_ptrauth_sign_generic_data(dp
, mismatched_type
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
130 (void) __builtin_ptrauth_sign_generic_data(NULL
, 0); // no warning
132 unsigned long dr
= __builtin_ptrauth_sign_generic_data(dp
, 0);
133 dr
= __builtin_ptrauth_sign_generic_data(dp
, &dv
);
134 dr
= __builtin_ptrauth_sign_generic_data(12314, 0);
135 dr
= __builtin_ptrauth_sign_generic_data(12314, &dv
);
137 int *mismatch
= __builtin_ptrauth_sign_generic_data(dp
, 0); // expected-error {{incompatible integer to pointer conversion initializing 'int *' with an expression of type}}
141 typedef int (*fp_t
)(int);
143 static int dv_weakref
__attribute__((weakref("dv")));
144 extern int dv_weak
__attribute__((weak
));
146 int *t_cst_sig1
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
); // expected-error {{too few arguments}}
147 int *t_cst_sig2
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, &dv
, &dv
); // expected-error {{too many arguments}}
149 int *t_cst_sig3
= __builtin_ptrauth_sign_constant(mismatched_type
, VALID_DATA_KEY
, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
150 int *t_cst_sig4
= __builtin_ptrauth_sign_constant(&dv
, mismatched_type
, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
151 int *t_cst_sig5
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, mismatched_type
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
153 float *t_cst_result
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
155 int *t_cst_valid1
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, 0);
156 int *t_cst_valid2
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&dv
, 0));
157 int *t_cst_valid3
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&dv
+ 8, 0));
158 int *t_cst_valid4
= __builtin_ptrauth_sign_constant(&dv_weak
, VALID_DATA_KEY
, 0);
159 int *t_cst_valid5
= __builtin_ptrauth_sign_constant(&dv_weakref
, VALID_DATA_KEY
, 0);
161 int *t_cst_ptr
= __builtin_ptrauth_sign_constant(NULL
, VALID_DATA_KEY
, &dv
); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
162 int *t_cst_key
= __builtin_ptrauth_sign_constant(&dv
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
163 int *t_cst_disc1
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, &fv
); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
164 int *t_cst_disc2
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&fv
, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
166 fp_t t_cst_f_valid1
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, 0);
167 fp_t t_cst_f_valid2
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&dv
, 0));
168 fp_t t_cst_f_valid3
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&dv
+ 8, 0));
170 fp_t t_cst_f_key
= __builtin_ptrauth_sign_constant(&fv
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
171 fp_t t_cst_f_disc1
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, &fv
); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
172 fp_t t_cst_f_disc2
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&fv
, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
174 int *t_cst_offset
= __builtin_ptrauth_sign_constant((int *)((char*)&dv
+ 16), VALID_DATA_KEY
, 0);
175 fp_t t_cst_f_offset
= __builtin_ptrauth_sign_constant((int (*)(int))((char*)&fv
+ 16), VALID_CODE_KEY
, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
177 void test_sign_constant(int *dp
, fp_t fp
) {
178 int *sig1
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
); // expected-error {{too few arguments}}
179 int *sig2
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, &dv
, &dv
); // expected-error {{too many arguments}}
181 int *sig3
= __builtin_ptrauth_sign_constant(mismatched_type
, VALID_DATA_KEY
, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
182 int *sig4
= __builtin_ptrauth_sign_constant(&dv
, mismatched_type
, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
183 int *sig5
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, mismatched_type
); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
185 float *result
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
187 int *valid1
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, 0);
188 int *valid2
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&dv
, 0));
189 int *valid3
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&dv
+ 8, 0));
190 int *valid4
= __builtin_ptrauth_sign_constant(&dv_weak
, VALID_DATA_KEY
, 0);
191 int *valid5
= __builtin_ptrauth_sign_constant(&dv_weakref
, VALID_DATA_KEY
, 0);
193 int *ptr
= __builtin_ptrauth_sign_constant(NULL
, VALID_DATA_KEY
, &dv
); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
194 int *key
= __builtin_ptrauth_sign_constant(&dv
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
195 int *disc1
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, &fv
); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
196 int *disc2
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&fv
, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
198 int *ptr2
= __builtin_ptrauth_sign_constant(dp
, VALID_DATA_KEY
, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
199 int *disc3
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, dp
); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
200 int *disc4
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(dp
, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
201 int *disc5
= __builtin_ptrauth_sign_constant(&dv
, VALID_DATA_KEY
, __builtin_ptrauth_blend_discriminator(&dv
, *dp
)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
203 fp_t f_valid1
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, 0);
204 fp_t f_valid2
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&dv
, 0));
205 fp_t f_valid3
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&dv
+ 8, 0));
207 fp_t f_key
= __builtin_ptrauth_sign_constant(&fv
, INVALID_KEY
, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
208 fp_t f_disc1
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, &fv
); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
209 fp_t f_disc2
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&fv
, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
211 fp_t f_ptr
= __builtin_ptrauth_sign_constant(fp
, VALID_CODE_KEY
, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
212 fp_t f_disc3
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, dp
); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
214 fp_t f_disc4
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(dp
, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
215 fp_t f_disc5
= __builtin_ptrauth_sign_constant(&fv
, VALID_CODE_KEY
, __builtin_ptrauth_blend_discriminator(&dv
, *dp
)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
217 int *offset
= __builtin_ptrauth_sign_constant((int *)((char*)&dv
+ 16), VALID_DATA_KEY
, 0);
218 fp_t f_offset
= __builtin_ptrauth_sign_constant((fp_t
)((char*)&fv
+ 16), VALID_CODE_KEY
, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}