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