1*bbb1b6f9SApple OSS Distributions /*===---- ptrcheck.h - Pointer bounds hints & specifications ----------------=== 2*bbb1b6f9SApple OSS Distributions * 3*bbb1b6f9SApple OSS Distributions * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bbb1b6f9SApple OSS Distributions * See https://llvm.org/LICENSE.txt for license information. 5*bbb1b6f9SApple OSS Distributions * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bbb1b6f9SApple OSS Distributions * 7*bbb1b6f9SApple OSS Distributions *===-----------------------------------------------------------------------=== 8*bbb1b6f9SApple OSS Distributions */ 9*bbb1b6f9SApple OSS Distributions 10*bbb1b6f9SApple OSS Distributions #ifndef __PTRCHECK_H 11*bbb1b6f9SApple OSS Distributions #define __PTRCHECK_H 12*bbb1b6f9SApple OSS Distributions 13*bbb1b6f9SApple OSS Distributions /* __has_ptrcheck can be used in preprocessor macros (and other parts of the 14*bbb1b6f9SApple OSS Distributions language expecting constant expressions) to test if bounds attributes 15*bbb1b6f9SApple OSS Distributions exist. */ 16*bbb1b6f9SApple OSS Distributions #if defined(__has_feature) && __has_feature(bounds_attributes) 17*bbb1b6f9SApple OSS Distributions #define __has_ptrcheck 1 18*bbb1b6f9SApple OSS Distributions #else 19*bbb1b6f9SApple OSS Distributions #define __has_ptrcheck 0 20*bbb1b6f9SApple OSS Distributions #endif 21*bbb1b6f9SApple OSS Distributions 22*bbb1b6f9SApple OSS Distributions #if __has_ptrcheck 23*bbb1b6f9SApple OSS Distributions 24*bbb1b6f9SApple OSS Distributions /* An attribute that modifies a pointer type such that its ABI is three pointer 25*bbb1b6f9SApple OSS Distributions components: the pointer value itself (the pointer value); one-past-the-end of 26*bbb1b6f9SApple OSS Distributions the object it is derived from (the upper bound); and the base address of the 27*bbb1b6f9SApple OSS Distributions object it is derived from (the lower bound). The pointer value is allowed to 28*bbb1b6f9SApple OSS Distributions lie outside the [lower bound, upper bound) interval, and it supports the 29*bbb1b6f9SApple OSS Distributions entire range of arithmetic operations that are usually applicable to 30*bbb1b6f9SApple OSS Distributions pointers. Bounds are implicitly checked only when the pointer is dereferenced 31*bbb1b6f9SApple OSS Distributions or converted to a different representation. */ 32*bbb1b6f9SApple OSS Distributions #define __bidi_indexable __attribute__((__bidi_indexable__)) 33*bbb1b6f9SApple OSS Distributions 34*bbb1b6f9SApple OSS Distributions /* An attribute that modifies a pointer type such that its ABI is two pointer 35*bbb1b6f9SApple OSS Distributions components: the pointer value itself (the lower bound); and one-past-the-end 36*bbb1b6f9SApple OSS Distributions of the object it is derived from (the upper bound). Indexable pointers do not 37*bbb1b6f9SApple OSS Distributions support negative arithmetic operations: it is a compile-time error to use a 38*bbb1b6f9SApple OSS Distributions subtraction or add a negative quantity to them, and it is a runtime error if 39*bbb1b6f9SApple OSS Distributions the same happens at runtime while it can't be detected at compile-time. Same 40*bbb1b6f9SApple OSS Distributions as __bidi_indexable pointers, __indexable pointers are bounds-checked when 41*bbb1b6f9SApple OSS Distributions dereferenced or converted to another representation. */ 42*bbb1b6f9SApple OSS Distributions #define __indexable __attribute__((__indexable__)) 43*bbb1b6f9SApple OSS Distributions 44*bbb1b6f9SApple OSS Distributions /* An attribute that modifies a pointer type such than it has the ABI of a 45*bbb1b6f9SApple OSS Distributions regular C pointer, without allowing pointer arithmetic. Pointer arithmetic is 46*bbb1b6f9SApple OSS Distributions a compile-time error. A __single pointer is expected to be either NULL or 47*bbb1b6f9SApple OSS Distributions point to exactly one valid value. */ 48*bbb1b6f9SApple OSS Distributions #define __single __attribute__((__single__)) 49*bbb1b6f9SApple OSS Distributions 50*bbb1b6f9SApple OSS Distributions /* An attribute that modifies a pointer type such than it can be used exactly 51*bbb1b6f9SApple OSS Distributions like a regular C pointer, with unchecked arithmetic and dereferencing. An 52*bbb1b6f9SApple OSS Distributions __unsafe_indexable pointer cannot convert implicitly to another type of 53*bbb1b6f9SApple OSS Distributions pointer since that would require information that is not available to the 54*bbb1b6f9SApple OSS Distributions program. You must use __unsafe_forge_bidi_indexable or __unsafe_forge_single 55*bbb1b6f9SApple OSS Distributions to convert __unsafe_indexable pointers to so-called safe pointers. */ 56*bbb1b6f9SApple OSS Distributions #define __unsafe_indexable __attribute__((__unsafe_indexable__)) 57*bbb1b6f9SApple OSS Distributions 58*bbb1b6f9SApple OSS Distributions /* An attribute that modifies a pointer type such that it has the ABI of a 59*bbb1b6f9SApple OSS Distributions regular C pointer, but it implicitly converts to a __bidi_indexable pointer 60*bbb1b6f9SApple OSS Distributions with bounds that assume there are N valid elements starting at its address. 61*bbb1b6f9SApple OSS Distributions The conversion happens at the same point the object converts to an rvalue, or 62*bbb1b6f9SApple OSS Distributions immediately for values which cannot be lvalues (such as function calls). */ 63*bbb1b6f9SApple OSS Distributions 64*bbb1b6f9SApple OSS Distributions /* Assignments to the pointer object must be accompanied with an assignment to 65*bbb1b6f9SApple OSS Distributions N if it is assignable. */ 66*bbb1b6f9SApple OSS Distributions 67*bbb1b6f9SApple OSS Distributions /* N must either be an expression that evaluates to a constant, or an integer 68*bbb1b6f9SApple OSS Distributions declaration from the same scope, or (for structure fields) a declaration 69*bbb1b6f9SApple OSS Distributions contained in basic arithmetic. */ 70*bbb1b6f9SApple OSS Distributions #define __counted_by(N) __attribute__((__counted_by__(N))) 71*bbb1b6f9SApple OSS Distributions 72*bbb1b6f9SApple OSS Distributions /* Identical to __counted_by(N), aside that the pointer may be null for 73*bbb1b6f9SApple OSS Distributions * non-zero values of N. */ 74*bbb1b6f9SApple OSS Distributions #define __counted_by_or_null(N) __attribute__((__counted_by_or_null__(N))) 75*bbb1b6f9SApple OSS Distributions 76*bbb1b6f9SApple OSS Distributions /* Identical to __counted_by(N), aside that N is a byte count instead of an 77*bbb1b6f9SApple OSS Distributions object count. */ 78*bbb1b6f9SApple OSS Distributions #define __sized_by(N) __attribute__((__sized_by__(N))) 79*bbb1b6f9SApple OSS Distributions 80*bbb1b6f9SApple OSS Distributions /* Identical to __sized_by(N), aside that the pointer may be null for non-zero 81*bbb1b6f9SApple OSS Distributions * values of N. */ 82*bbb1b6f9SApple OSS Distributions #define __sized_by_or_null(N) __attribute__((__sized_by_or_null__(N))) 83*bbb1b6f9SApple OSS Distributions 84*bbb1b6f9SApple OSS Distributions /* An attribute that modifies a pointer type such that it has the ABI of a 85*bbb1b6f9SApple OSS Distributions regular C pointer, but it implicitly converts to a __bidi_indexable pointer 86*bbb1b6f9SApple OSS Distributions with bounds that assume that E is one-past-the-end of the original object. 87*bbb1b6f9SApple OSS Distributions Implicitly, referencing E in the same scope will create a pointer that 88*bbb1b6f9SApple OSS Distributions converts to a __bidi_indexable pointer one-past-the-end of the original 89*bbb1b6f9SApple OSS Distributions object, but with a lower bound set to the value of the pointer that is 90*bbb1b6f9SApple OSS Distributions attributed. */ 91*bbb1b6f9SApple OSS Distributions 92*bbb1b6f9SApple OSS Distributions /* Assignments to the pointer object must be accompanied with an assignment to 93*bbb1b6f9SApple OSS Distributions E if it is assignable. */ 94*bbb1b6f9SApple OSS Distributions #define __ended_by(E) __attribute__((__ended_by__(E))) 95*bbb1b6f9SApple OSS Distributions 96*bbb1b6f9SApple OSS Distributions /* The __terminated_by(T) attribute can be applied to arrays and pointers. The 97*bbb1b6f9SApple OSS Distributions argument T specifies the terminator and must be an integer constant 98*bbb1b6f9SApple OSS Distributions expression. Even though T has to be an integer constant, __terminated_by(T) 99*bbb1b6f9SApple OSS Distributions can be applied to pointer arrays as well. For convenience, the 100*bbb1b6f9SApple OSS Distributions __null_terminated macro is provided, which is equivalent to 101*bbb1b6f9SApple OSS Distributions __terminated_by(0). 102*bbb1b6f9SApple OSS Distributions 103*bbb1b6f9SApple OSS Distributions The __terminated_by(T) attribute can be applied only to __single pointers. If 104*bbb1b6f9SApple OSS Distributions the pointer attribute is not specified, it is automatically set to __single. 105*bbb1b6f9SApple OSS Distributions A __terminated_by(T) pointer points to the first element of an array that is 106*bbb1b6f9SApple OSS Distributions terminated with T. 107*bbb1b6f9SApple OSS Distributions 108*bbb1b6f9SApple OSS Distributions Arithmetic on __terminated_by(T) pointers is restricted to only incrementing 109*bbb1b6f9SApple OSS Distributions the pointer by one, and must be able to be evaluated at compile-time. 110*bbb1b6f9SApple OSS Distributions Pointer arithmetic generates a runtime check to ensure that the pointer 111*bbb1b6f9SApple OSS Distributions doesn't point pass the terminator. 112*bbb1b6f9SApple OSS Distributions 113*bbb1b6f9SApple OSS Distributions A __terminated_by(T) pointer has the ABI of a regular C pointer. 114*bbb1b6f9SApple OSS Distributions 115*bbb1b6f9SApple OSS Distributions When __terminated_by(T) is applied to an array, the compiler checks if the 116*bbb1b6f9SApple OSS Distributions array is terminated with the given terminator T during the initialization. 117*bbb1b6f9SApple OSS Distributions Moreover, a __terminated_by(T) array decays to a __terminated_by(T) __single 118*bbb1b6f9SApple OSS Distributions pointer, instead of decaying to a __bidi_indexable pointer. */ 119*bbb1b6f9SApple OSS Distributions #define __terminated_by(T) __attribute__((__terminated_by__(T))) 120*bbb1b6f9SApple OSS Distributions #define __null_terminated __terminated_by(0) 121*bbb1b6f9SApple OSS Distributions 122*bbb1b6f9SApple OSS Distributions /* Directives that tells the compiler to assume that subsequent pointer types 123*bbb1b6f9SApple OSS Distributions have the ABI specified by the ABI parameter, which may be one of single, 124*bbb1b6f9SApple OSS Distributions indexable, bidi_indexable or unsafe_indexable. */ 125*bbb1b6f9SApple OSS Distributions 126*bbb1b6f9SApple OSS Distributions /* In project files, the ABI is assumed to be single by default. In headers 127*bbb1b6f9SApple OSS Distributions included from libraries or the SDK, the ABI is assumed to be unsafe_indexable 128*bbb1b6f9SApple OSS Distributions by default. */ 129*bbb1b6f9SApple OSS Distributions #define __ptrcheck_abi_assume_single() \ 130*bbb1b6f9SApple OSS Distributions _Pragma("clang abi_ptr_attr set(single)") 131*bbb1b6f9SApple OSS Distributions 132*bbb1b6f9SApple OSS Distributions #define __ptrcheck_abi_assume_indexable() \ 133*bbb1b6f9SApple OSS Distributions _Pragma("clang abi_ptr_attr set(indexable)") 134*bbb1b6f9SApple OSS Distributions 135*bbb1b6f9SApple OSS Distributions #define __ptrcheck_abi_assume_bidi_indexable() \ 136*bbb1b6f9SApple OSS Distributions _Pragma("clang abi_ptr_attr set(bidi_indexable)") 137*bbb1b6f9SApple OSS Distributions 138*bbb1b6f9SApple OSS Distributions #define __ptrcheck_abi_assume_unsafe_indexable() \ 139*bbb1b6f9SApple OSS Distributions _Pragma("clang abi_ptr_attr set(unsafe_indexable)") 140*bbb1b6f9SApple OSS Distributions 141*bbb1b6f9SApple OSS Distributions /* Create a __bidi_indexable pointer of a given pointer type (T), starting at 142*bbb1b6f9SApple OSS Distributions address P, pointing to S bytes of valid memory. T must be a pointer type. */ 143*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_bidi_indexable(T, P, S) \ 144*bbb1b6f9SApple OSS Distributions ((T __bidi_indexable)__builtin_unsafe_forge_bidi_indexable((P), (S))) 145*bbb1b6f9SApple OSS Distributions 146*bbb1b6f9SApple OSS Distributions /* Create a __single pointer of a given type (T), starting at address P. T must 147*bbb1b6f9SApple OSS Distributions be a pointer type. */ 148*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_single(T, P) \ 149*bbb1b6f9SApple OSS Distributions ((T __single)__builtin_unsafe_forge_single((P))) 150*bbb1b6f9SApple OSS Distributions 151*bbb1b6f9SApple OSS Distributions /* Create a __terminated_by pointer of a given pointer type (T), starting at 152*bbb1b6f9SApple OSS Distributions address P, terminated by E. T must be a pointer type. */ 153*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_terminated_by(T, P, E) \ 154*bbb1b6f9SApple OSS Distributions ((T __terminated_by(E))__builtin_unsafe_forge_terminated_by((P), (E))) 155*bbb1b6f9SApple OSS Distributions 156*bbb1b6f9SApple OSS Distributions /* Create a __terminated_by pointer of a given pointer type (T), starting at 157*bbb1b6f9SApple OSS Distributions address P, terminated by 0. T must be a pointer type. */ 158*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_null_terminated(T, P) __unsafe_forge_terminated_by(T, P, 0) 159*bbb1b6f9SApple OSS Distributions 160*bbb1b6f9SApple OSS Distributions /* Create a wide pointer with the same lower bound and upper bounds as X, but 161*bbb1b6f9SApple OSS Distributions with a pointer component also equal to the lower bound. */ 162*bbb1b6f9SApple OSS Distributions #define __ptr_lower_bound(X) __builtin_get_pointer_lower_bound(X) 163*bbb1b6f9SApple OSS Distributions 164*bbb1b6f9SApple OSS Distributions /* Create a wide pointer with the same lower bound and upper bounds as X, but 165*bbb1b6f9SApple OSS Distributions with a pointer component also equal to the upper bound. */ 166*bbb1b6f9SApple OSS Distributions #define __ptr_upper_bound(X) __builtin_get_pointer_upper_bound(X) 167*bbb1b6f9SApple OSS Distributions 168*bbb1b6f9SApple OSS Distributions /* Convert a __terminated_by(T) pointer to an __indexable pointer. These 169*bbb1b6f9SApple OSS Distributions operations will calculate the upper bound by iterating over the memory 170*bbb1b6f9SApple OSS Distributions pointed to by P in order to find the terminator. 171*bbb1b6f9SApple OSS Distributions 172*bbb1b6f9SApple OSS Distributions The __terminated_by_to_indexable(P) does NOT include the terminator within 173*bbb1b6f9SApple OSS Distributions bounds of the __indexable pointer. Consequently, the terminator cannot be 174*bbb1b6f9SApple OSS Distributions erased (or even accessed) through the __indexable pointer. The address one 175*bbb1b6f9SApple OSS Distributions past the end of the array (pointing to the terminator) can be found with 176*bbb1b6f9SApple OSS Distributions __ptr_upper_bound(). 177*bbb1b6f9SApple OSS Distributions 178*bbb1b6f9SApple OSS Distributions The __unsafe_terminated_by_to_indexable(P) does include the terminator within 179*bbb1b6f9SApple OSS Distributions the bounds of the __indexable pointer. This makes the operation unsafe, since 180*bbb1b6f9SApple OSS Distributions the terminator can be erased, and thus using P might result in out-of-bounds 181*bbb1b6f9SApple OSS Distributions access. */ 182*bbb1b6f9SApple OSS Distributions #define __terminated_by_to_indexable(P) \ 183*bbb1b6f9SApple OSS Distributions __builtin_terminated_by_to_indexable(P) 184*bbb1b6f9SApple OSS Distributions #define __unsafe_terminated_by_to_indexable(P) \ 185*bbb1b6f9SApple OSS Distributions __builtin_unsafe_terminated_by_to_indexable(P) 186*bbb1b6f9SApple OSS Distributions 187*bbb1b6f9SApple OSS Distributions #define __null_terminated_to_indexable(P) \ 188*bbb1b6f9SApple OSS Distributions ({ \ 189*bbb1b6f9SApple OSS Distributions __typeof__(*(P)) *__null_terminated __ptr = (P); \ 190*bbb1b6f9SApple OSS Distributions __terminated_by_to_indexable(__ptr); \ 191*bbb1b6f9SApple OSS Distributions }) 192*bbb1b6f9SApple OSS Distributions 193*bbb1b6f9SApple OSS Distributions #define __unsafe_null_terminated_to_indexable(P) \ 194*bbb1b6f9SApple OSS Distributions ({ \ 195*bbb1b6f9SApple OSS Distributions __typeof__(*(P)) *__null_terminated __ptr = (P); \ 196*bbb1b6f9SApple OSS Distributions __unsafe_terminated_by_to_indexable(__ptr); \ 197*bbb1b6f9SApple OSS Distributions }) 198*bbb1b6f9SApple OSS Distributions 199*bbb1b6f9SApple OSS Distributions /* __unsafe_terminated_by_from_indexable(T, PTR [, PTR_TO_TERM]) converts an 200*bbb1b6f9SApple OSS Distributions __indexable pointer to a __terminated_by(T) pointer. The operation will 201*bbb1b6f9SApple OSS Distributions check if the given terminator T occurs in the memory pointed to by PTR. 202*bbb1b6f9SApple OSS Distributions If so, the operation evaluates to __terminated_by(T) pointer. Otherwise, it 203*bbb1b6f9SApple OSS Distributions traps. 204*bbb1b6f9SApple OSS Distributions 205*bbb1b6f9SApple OSS Distributions The operation has an optional parameter PTR_TO_TERM, which changes the way 206*bbb1b6f9SApple OSS Distributions how the check for the terminator existence is generated. PTR_TO_TERM must 207*bbb1b6f9SApple OSS Distributions point to the terminator element and be within the bounds of PTR. 208*bbb1b6f9SApple OSS Distributions If PTR_TO_TERM is provided, the runtime will check if it is in fact within 209*bbb1b6f9SApple OSS Distributions the bounds and points to an element that equals to T. If PTR_TO_TERM is not 210*bbb1b6f9SApple OSS Distributions provided, the runtime will iterate over the memory pointed to by PTR to find 211*bbb1b6f9SApple OSS Distributions the terminator. 212*bbb1b6f9SApple OSS Distributions 213*bbb1b6f9SApple OSS Distributions The operation is unsafe, since the terminator can be erased through PTR after 214*bbb1b6f9SApple OSS Distributions the conversion. This can result in out-of-bounds access through the newly 215*bbb1b6f9SApple OSS Distributions created __terminated_by(T) pointer. 216*bbb1b6f9SApple OSS Distributions 217*bbb1b6f9SApple OSS Distributions For convenience, the 218*bbb1b6f9SApple OSS Distributions __unsafe_null_terminated_from_indexable(PTR [, PTR_TO_TERM]) macro is 219*bbb1b6f9SApple OSS Distributions provided, which assumes that the terminator is 0. */ 220*bbb1b6f9SApple OSS Distributions #define __unsafe_terminated_by_from_indexable(T, ...) \ 221*bbb1b6f9SApple OSS Distributions __builtin_unsafe_terminated_by_from_indexable((T), __VA_ARGS__) 222*bbb1b6f9SApple OSS Distributions #define __unsafe_null_terminated_from_indexable(...) \ 223*bbb1b6f9SApple OSS Distributions __builtin_unsafe_terminated_by_from_indexable(0, __VA_ARGS__) 224*bbb1b6f9SApple OSS Distributions 225*bbb1b6f9SApple OSS Distributions /* Instruct the compiler to disregard the bounds of an array used in a function 226*bbb1b6f9SApple OSS Distributions prototype and allow the decayed pointer to use __counted_by. This is a niche 227*bbb1b6f9SApple OSS Distributions capability that is only useful in limited patterns (the way that `mig` uses 228*bbb1b6f9SApple OSS Distributions arrays being one of them). */ 229*bbb1b6f9SApple OSS Distributions #define __array_decay_dicards_count_in_parameters \ 230*bbb1b6f9SApple OSS Distributions __attribute__((__decay_discards_count_in_parameters__)) 231*bbb1b6f9SApple OSS Distributions 232*bbb1b6f9SApple OSS Distributions /* An attribute to indicate a variable to be effectively constant (or data const) 233*bbb1b6f9SApple OSS Distributions that it is allocated in a const section so cannot be modified after an early 234*bbb1b6f9SApple OSS Distributions stage of bootup, for example. Adding this attribute allows a global variable 235*bbb1b6f9SApple OSS Distributions to be used in __counted_by attribute of struct fields, function parameter, or 236*bbb1b6f9SApple OSS Distributions local variable just like actual constants. 237*bbb1b6f9SApple OSS Distributions Note that ensuring the value never changes once it is used is the user's 238*bbb1b6f9SApple OSS Distributions responsibility. One way to achieve this is the xnu model, in which certain 239*bbb1b6f9SApple OSS Distributions variables are placed in a segment that is remapped as read-only after 240*bbb1b6f9SApple OSS Distributions initialization. */ 241*bbb1b6f9SApple OSS Distributions #define __unsafe_late_const __attribute__((__unsafe_late_const__)) 242*bbb1b6f9SApple OSS Distributions 243*bbb1b6f9SApple OSS Distributions /* An attribute to indicate that a function is unavailable when -fbounds-safety 244*bbb1b6f9SApple OSS Distributions is enabled because it is unsafe. Calls to functions annotated with this 245*bbb1b6f9SApple OSS Distributions attribute are errors when -fbounds-safety is enabled, but are allowed when 246*bbb1b6f9SApple OSS Distributions -fbounds-safety is disabled. 247*bbb1b6f9SApple OSS Distributions 248*bbb1b6f9SApple OSS Distributions Example: 249*bbb1b6f9SApple OSS Distributions 250*bbb1b6f9SApple OSS Distributions void* __ptrcheck_unavailable some_unsafe_api(void*); 251*bbb1b6f9SApple OSS Distributions */ 252*bbb1b6f9SApple OSS Distributions #define __ptrcheck_unavailable \ 253*bbb1b6f9SApple OSS Distributions __attribute__((__unavailable__("unavailable with -fbounds-safety."))) 254*bbb1b6f9SApple OSS Distributions 255*bbb1b6f9SApple OSS Distributions /* __ptrcheck_unavailable_r is the same as __ptrcheck_unavailable but it takes 256*bbb1b6f9SApple OSS Distributions as an argument the name of replacement function that is safe for use with 257*bbb1b6f9SApple OSS Distributions -fbounds-safety enabled. 258*bbb1b6f9SApple OSS Distributions 259*bbb1b6f9SApple OSS Distributions Example: 260*bbb1b6f9SApple OSS Distributions 261*bbb1b6f9SApple OSS Distributions void* __counted_by(size) safe_api(void* __counted_by(size), size_t size); 262*bbb1b6f9SApple OSS Distributions 263*bbb1b6f9SApple OSS Distributions void* __ptrcheck_unavailable_r(safe_api) some_unsafe_api(void*); 264*bbb1b6f9SApple OSS Distributions */ 265*bbb1b6f9SApple OSS Distributions #define __ptrcheck_unavailable_r(REPLACEMENT) \ 266*bbb1b6f9SApple OSS Distributions __attribute__((__unavailable__( \ 267*bbb1b6f9SApple OSS Distributions "unavailable with -fbounds-safety. Use " #REPLACEMENT " instead."))) 268*bbb1b6f9SApple OSS Distributions 269*bbb1b6f9SApple OSS Distributions #else 270*bbb1b6f9SApple OSS Distributions 271*bbb1b6f9SApple OSS Distributions /* We intentionally define to nothing pointer attributes which do not have an 272*bbb1b6f9SApple OSS Distributions impact on the ABI. __indexable and __bidi_indexable are not defined because 273*bbb1b6f9SApple OSS Distributions of the ABI incompatibility that makes the diagnostic preferable. */ 274*bbb1b6f9SApple OSS Distributions #define __single 275*bbb1b6f9SApple OSS Distributions #define __unsafe_indexable 276*bbb1b6f9SApple OSS Distributions #define __counted_by(N) 277*bbb1b6f9SApple OSS Distributions #define __counted_by_or_null(N) 278*bbb1b6f9SApple OSS Distributions #define __sized_by(N) 279*bbb1b6f9SApple OSS Distributions #define __sized_by_or_null(N) 280*bbb1b6f9SApple OSS Distributions #define __ended_by(E) 281*bbb1b6f9SApple OSS Distributions 282*bbb1b6f9SApple OSS Distributions /* We intentionally define the terminated_by attributes to nothing. */ 283*bbb1b6f9SApple OSS Distributions #define __terminated_by(T) 284*bbb1b6f9SApple OSS Distributions #define __null_terminated 285*bbb1b6f9SApple OSS Distributions 286*bbb1b6f9SApple OSS Distributions /* Similarly, we intentionally define to nothing the 287*bbb1b6f9SApple OSS Distributions __ptrcheck_abi_assume_single and __ptrcheck_abi_assume_unsafe_indexable 288*bbb1b6f9SApple OSS Distributions macros because they do not lead to an ABI incompatibility. However, we do not 289*bbb1b6f9SApple OSS Distributions define the indexable and unsafe_indexable ones because the diagnostic is 290*bbb1b6f9SApple OSS Distributions better than the silent ABI break. */ 291*bbb1b6f9SApple OSS Distributions #define __ptrcheck_abi_assume_single() 292*bbb1b6f9SApple OSS Distributions #define __ptrcheck_abi_assume_unsafe_indexable() 293*bbb1b6f9SApple OSS Distributions 294*bbb1b6f9SApple OSS Distributions /* __unsafe_forge intrinsics are defined as regular C casts. */ 295*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_bidi_indexable(T, P, S) ((T)(P)) 296*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_single(T, P) ((T)(P)) 297*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_terminated_by(T, P, E) ((T)(P)) 298*bbb1b6f9SApple OSS Distributions #define __unsafe_forge_null_terminated(T, P) ((T)(P)) 299*bbb1b6f9SApple OSS Distributions 300*bbb1b6f9SApple OSS Distributions /* The conversion between terminated_by pointers just evaluates to the pointer 301*bbb1b6f9SApple OSS Distributions argument. */ 302*bbb1b6f9SApple OSS Distributions #define __terminated_by_to_indexable(P) (P) 303*bbb1b6f9SApple OSS Distributions #define __unsafe_terminated_by_to_indexable(P) (P) 304*bbb1b6f9SApple OSS Distributions #define __null_terminated_to_indexable(P) (P) 305*bbb1b6f9SApple OSS Distributions #define __unsafe_null_terminated_to_indexable(P) (P) 306*bbb1b6f9SApple OSS Distributions #define __unsafe_terminated_by_from_indexable(T, P, ...) (P) 307*bbb1b6f9SApple OSS Distributions #define __unsafe_null_terminated_from_indexable(P, ...) (P) 308*bbb1b6f9SApple OSS Distributions 309*bbb1b6f9SApple OSS Distributions /* decay operates normally; attribute is meaningless without pointer checks. */ 310*bbb1b6f9SApple OSS Distributions #define __array_decay_dicards_count_in_parameters 311*bbb1b6f9SApple OSS Distributions 312*bbb1b6f9SApple OSS Distributions /* The APIs marked with these attributes are available outside the context of 313*bbb1b6f9SApple OSS Distributions pointer checks, so do nothing. */ 314*bbb1b6f9SApple OSS Distributions #define __ptrcheck_unavailable 315*bbb1b6f9SApple OSS Distributions #define __ptrcheck_unavailable_r(REPLACEMENT) 316*bbb1b6f9SApple OSS Distributions 317*bbb1b6f9SApple OSS Distributions #endif /* __has_ptrcheck */ 318*bbb1b6f9SApple OSS Distributions 319*bbb1b6f9SApple OSS Distributions #endif /* __PTRCHECK_H */ 320