1*1031c584SApple OSS Distributions /* 2*1031c584SApple OSS Distributions * Copyright (c) 2008-2020 Apple Inc. All rights reserved. 3*1031c584SApple OSS Distributions * 4*1031c584SApple OSS Distributions * @APPLE_APACHE_LICENSE_HEADER_START@ 5*1031c584SApple OSS Distributions * 6*1031c584SApple OSS Distributions * Licensed under the Apache License, Version 2.0 (the "License"); 7*1031c584SApple OSS Distributions * you may not use this file except in compliance with the License. 8*1031c584SApple OSS Distributions * You may obtain a copy of the License at 9*1031c584SApple OSS Distributions * 10*1031c584SApple OSS Distributions * http://www.apache.org/licenses/LICENSE-2.0 11*1031c584SApple OSS Distributions * 12*1031c584SApple OSS Distributions * Unless required by applicable law or agreed to in writing, software 13*1031c584SApple OSS Distributions * distributed under the License is distributed on an "AS IS" BASIS, 14*1031c584SApple OSS Distributions * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*1031c584SApple OSS Distributions * See the License for the specific language governing permissions and 16*1031c584SApple OSS Distributions * limitations under the License. 17*1031c584SApple OSS Distributions * 18*1031c584SApple OSS Distributions * @APPLE_APACHE_LICENSE_HEADER_END@ 19*1031c584SApple OSS Distributions */ 20*1031c584SApple OSS Distributions 21*1031c584SApple OSS Distributions #ifndef __OS_BASE__ 22*1031c584SApple OSS Distributions #define __OS_BASE__ 23*1031c584SApple OSS Distributions 24*1031c584SApple OSS Distributions #include <sys/cdefs.h> 25*1031c584SApple OSS Distributions 26*1031c584SApple OSS Distributions 27*1031c584SApple OSS Distributions #ifndef __has_builtin 28*1031c584SApple OSS Distributions #define __has_builtin(x) 0 29*1031c584SApple OSS Distributions #endif 30*1031c584SApple OSS Distributions #ifndef __has_include 31*1031c584SApple OSS Distributions #define __has_include(x) 0 32*1031c584SApple OSS Distributions #endif 33*1031c584SApple OSS Distributions #ifndef __has_feature 34*1031c584SApple OSS Distributions #define __has_feature(x) 0 35*1031c584SApple OSS Distributions #endif 36*1031c584SApple OSS Distributions #ifndef __has_attribute 37*1031c584SApple OSS Distributions #define __has_attribute(x) 0 38*1031c584SApple OSS Distributions #endif 39*1031c584SApple OSS Distributions #ifndef __has_extension 40*1031c584SApple OSS Distributions #define __has_extension(x) 0 41*1031c584SApple OSS Distributions #endif 42*1031c584SApple OSS Distributions 43*1031c584SApple OSS Distributions #undef OS_INLINE // <sys/_types/_os_inline.h> 44*1031c584SApple OSS Distributions #if __GNUC__ 45*1031c584SApple OSS Distributions #define OS_NORETURN __attribute__((__noreturn__)) 46*1031c584SApple OSS Distributions #define OS_NOTHROW __attribute__((__nothrow__)) 47*1031c584SApple OSS Distributions #define OS_NONNULL1 __attribute__((__nonnull__(1))) 48*1031c584SApple OSS Distributions #define OS_NONNULL2 __attribute__((__nonnull__(2))) 49*1031c584SApple OSS Distributions #define OS_NONNULL3 __attribute__((__nonnull__(3))) 50*1031c584SApple OSS Distributions #define OS_NONNULL4 __attribute__((__nonnull__(4))) 51*1031c584SApple OSS Distributions #define OS_NONNULL5 __attribute__((__nonnull__(5))) 52*1031c584SApple OSS Distributions #define OS_NONNULL6 __attribute__((__nonnull__(6))) 53*1031c584SApple OSS Distributions #define OS_NONNULL7 __attribute__((__nonnull__(7))) 54*1031c584SApple OSS Distributions #define OS_NONNULL8 __attribute__((__nonnull__(8))) 55*1031c584SApple OSS Distributions #define OS_NONNULL9 __attribute__((__nonnull__(9))) 56*1031c584SApple OSS Distributions #define OS_NONNULL10 __attribute__((__nonnull__(10))) 57*1031c584SApple OSS Distributions #define OS_NONNULL11 __attribute__((__nonnull__(11))) 58*1031c584SApple OSS Distributions #define OS_NONNULL12 __attribute__((__nonnull__(12))) 59*1031c584SApple OSS Distributions #define OS_NONNULL13 __attribute__((__nonnull__(13))) 60*1031c584SApple OSS Distributions #define OS_NONNULL14 __attribute__((__nonnull__(14))) 61*1031c584SApple OSS Distributions #define OS_NONNULL15 __attribute__((__nonnull__(15))) 62*1031c584SApple OSS Distributions #define OS_NONNULL_ALL __attribute__((__nonnull__)) 63*1031c584SApple OSS Distributions #define OS_SENTINEL __attribute__((__sentinel__)) 64*1031c584SApple OSS Distributions #define OS_PURE __attribute__((__pure__)) 65*1031c584SApple OSS Distributions #define OS_CONST __attribute__((__const__)) 66*1031c584SApple OSS Distributions #define OS_WARN_RESULT __attribute__((__warn_unused_result__)) 67*1031c584SApple OSS Distributions #define OS_MALLOC __attribute__((__malloc__)) 68*1031c584SApple OSS Distributions #define OS_USED __attribute__((__used__)) 69*1031c584SApple OSS Distributions #define OS_UNUSED __attribute__((__unused__)) 70*1031c584SApple OSS Distributions #define OS_COLD __attribute__((__cold__)) 71*1031c584SApple OSS Distributions #define OS_WEAK __attribute__((__weak__)) 72*1031c584SApple OSS Distributions #define OS_WEAK_IMPORT __attribute__((__weak_import__)) 73*1031c584SApple OSS Distributions #define OS_NOINLINE __attribute__((__noinline__)) 74*1031c584SApple OSS Distributions #define OS_ALWAYS_INLINE __attribute__((__always_inline__)) 75*1031c584SApple OSS Distributions #define OS_TRANSPARENT_UNION __attribute__((__transparent_union__)) 76*1031c584SApple OSS Distributions #define OS_ALIGNED(n) __attribute__((__aligned__((n)))) 77*1031c584SApple OSS Distributions #define OS_FORMAT_PRINTF(x, y) __attribute__((__format__(printf,x,y))) 78*1031c584SApple OSS Distributions #define OS_EXPORT extern __attribute__((__visibility__("default"))) 79*1031c584SApple OSS Distributions #define OS_INLINE static __inline__ 80*1031c584SApple OSS Distributions #define OS_EXPECT(x, v) __builtin_expect((x), (v)) 81*1031c584SApple OSS Distributions #else 82*1031c584SApple OSS Distributions #define OS_NORETURN 83*1031c584SApple OSS Distributions #define OS_NOTHROW 84*1031c584SApple OSS Distributions #define OS_NONNULL1 85*1031c584SApple OSS Distributions #define OS_NONNULL2 86*1031c584SApple OSS Distributions #define OS_NONNULL3 87*1031c584SApple OSS Distributions #define OS_NONNULL4 88*1031c584SApple OSS Distributions #define OS_NONNULL5 89*1031c584SApple OSS Distributions #define OS_NONNULL6 90*1031c584SApple OSS Distributions #define OS_NONNULL7 91*1031c584SApple OSS Distributions #define OS_NONNULL8 92*1031c584SApple OSS Distributions #define OS_NONNULL9 93*1031c584SApple OSS Distributions #define OS_NONNULL10 94*1031c584SApple OSS Distributions #define OS_NONNULL11 95*1031c584SApple OSS Distributions #define OS_NONNULL12 96*1031c584SApple OSS Distributions #define OS_NONNULL13 97*1031c584SApple OSS Distributions #define OS_NONNULL14 98*1031c584SApple OSS Distributions #define OS_NONNULL15 99*1031c584SApple OSS Distributions #define OS_NONNULL_ALL 100*1031c584SApple OSS Distributions #define OS_SENTINEL 101*1031c584SApple OSS Distributions #define OS_PURE 102*1031c584SApple OSS Distributions #define OS_CONST 103*1031c584SApple OSS Distributions #define OS_WARN_RESULT 104*1031c584SApple OSS Distributions #define OS_MALLOC 105*1031c584SApple OSS Distributions #define OS_USED 106*1031c584SApple OSS Distributions #define OS_UNUSED 107*1031c584SApple OSS Distributions #define OS_COLD 108*1031c584SApple OSS Distributions #define OS_WEAK 109*1031c584SApple OSS Distributions #define OS_WEAK_IMPORT 110*1031c584SApple OSS Distributions #define OS_NOINLINE 111*1031c584SApple OSS Distributions #define OS_ALWAYS_INLINE 112*1031c584SApple OSS Distributions #define OS_TRANSPARENT_UNION 113*1031c584SApple OSS Distributions #define OS_ALIGNED(n) 114*1031c584SApple OSS Distributions #define OS_FORMAT_PRINTF(x, y) 115*1031c584SApple OSS Distributions #define OS_EXPORT extern 116*1031c584SApple OSS Distributions #define OS_INLINE static inline 117*1031c584SApple OSS Distributions #define OS_EXPECT(x, v) (x) 118*1031c584SApple OSS Distributions #endif 119*1031c584SApple OSS Distributions 120*1031c584SApple OSS Distributions #if __has_attribute(noescape) 121*1031c584SApple OSS Distributions #define OS_NOESCAPE __attribute__((__noescape__)) 122*1031c584SApple OSS Distributions #else 123*1031c584SApple OSS Distributions #define OS_NOESCAPE 124*1031c584SApple OSS Distributions #endif 125*1031c584SApple OSS Distributions 126*1031c584SApple OSS Distributions #if defined(__cplusplus) && defined(__clang__) 127*1031c584SApple OSS Distributions #define OS_FALLTHROUGH [[clang::fallthrough]] 128*1031c584SApple OSS Distributions #elif __has_attribute(fallthrough) 129*1031c584SApple OSS Distributions #define OS_FALLTHROUGH __attribute__((__fallthrough__)) 130*1031c584SApple OSS Distributions #else 131*1031c584SApple OSS Distributions #define OS_FALLTHROUGH 132*1031c584SApple OSS Distributions #endif 133*1031c584SApple OSS Distributions 134*1031c584SApple OSS Distributions #if __has_feature(assume_nonnull) 135*1031c584SApple OSS Distributions #define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 136*1031c584SApple OSS Distributions #define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 137*1031c584SApple OSS Distributions #else 138*1031c584SApple OSS Distributions #define OS_ASSUME_NONNULL_BEGIN 139*1031c584SApple OSS Distributions #define OS_ASSUME_NONNULL_END 140*1031c584SApple OSS Distributions #endif 141*1031c584SApple OSS Distributions 142*1031c584SApple OSS Distributions #if __has_builtin(__builtin_assume) 143*1031c584SApple OSS Distributions #define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr) 144*1031c584SApple OSS Distributions #else 145*1031c584SApple OSS Distributions #define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr)) 146*1031c584SApple OSS Distributions #endif 147*1031c584SApple OSS Distributions 148*1031c584SApple OSS Distributions #if __has_extension(attribute_overloadable) 149*1031c584SApple OSS Distributions #define OS_OVERLOADABLE __attribute__((__overloadable__)) 150*1031c584SApple OSS Distributions #else 151*1031c584SApple OSS Distributions #define OS_OVERLOADABLE 152*1031c584SApple OSS Distributions #endif 153*1031c584SApple OSS Distributions 154*1031c584SApple OSS Distributions #if __has_attribute(analyzer_suppress) 155*1031c584SApple OSS Distributions #define OS_ANALYZER_SUPPRESS(RADAR) __attribute__((analyzer_suppress)) 156*1031c584SApple OSS Distributions #else 157*1031c584SApple OSS Distributions #define OS_ANALYZER_SUPPRESS(RADAR) 158*1031c584SApple OSS Distributions #endif 159*1031c584SApple OSS Distributions 160*1031c584SApple OSS Distributions #if __has_attribute(enum_extensibility) 161*1031c584SApple OSS Distributions #define __OS_ENUM_ATTR __attribute__((enum_extensibility(open))) 162*1031c584SApple OSS Distributions #define __OS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed))) 163*1031c584SApple OSS Distributions #else 164*1031c584SApple OSS Distributions #define __OS_ENUM_ATTR 165*1031c584SApple OSS Distributions #define __OS_ENUM_ATTR_CLOSED 166*1031c584SApple OSS Distributions #endif // __has_attribute(enum_extensibility) 167*1031c584SApple OSS Distributions 168*1031c584SApple OSS Distributions #if __has_attribute(flag_enum) 169*1031c584SApple OSS Distributions /*! 170*1031c584SApple OSS Distributions * Compile with -Wflag-enum and -Wassign-enum to enforce at definition and 171*1031c584SApple OSS Distributions * assignment, respectively, i.e. -Wflag-enum prevents you from creating new 172*1031c584SApple OSS Distributions * enumeration values from illegal values within the enum definition, and 173*1031c584SApple OSS Distributions * -Wassign-enum prevents you from assigning illegal values to a variable of the 174*1031c584SApple OSS Distributions * enum type. 175*1031c584SApple OSS Distributions */ 176*1031c584SApple OSS Distributions #define __OS_OPTIONS_ATTR __attribute__((flag_enum)) 177*1031c584SApple OSS Distributions #else 178*1031c584SApple OSS Distributions #define __OS_OPTIONS_ATTR 179*1031c584SApple OSS Distributions #endif // __has_attribute(flag_enum) 180*1031c584SApple OSS Distributions 181*1031c584SApple OSS Distributions #if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || \ 182*1031c584SApple OSS Distributions __has_extension(cxx_strong_enums) 183*1031c584SApple OSS Distributions #define OS_ENUM(_name, _type, ...) \ 184*1031c584SApple OSS Distributions typedef enum : _type { __VA_ARGS__ } _name##_t 185*1031c584SApple OSS Distributions #define OS_CLOSED_ENUM(_name, _type, ...) \ 186*1031c584SApple OSS Distributions typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED _name##_t 187*1031c584SApple OSS Distributions #define OS_OPTIONS(_name, _type, ...) \ 188*1031c584SApple OSS Distributions typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR __OS_OPTIONS_ATTR _name##_t 189*1031c584SApple OSS Distributions #define OS_CLOSED_OPTIONS(_name, _type, ...) \ 190*1031c584SApple OSS Distributions typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR _name##_t 191*1031c584SApple OSS Distributions #else 192*1031c584SApple OSS Distributions /*! 193*1031c584SApple OSS Distributions * There is unfortunately no good way in plain C to have both fixed-type enums 194*1031c584SApple OSS Distributions * and enforcement for clang's enum_extensibility extensions. The primary goal 195*1031c584SApple OSS Distributions * of these macros is to allow you to define an enum and specify its width in a 196*1031c584SApple OSS Distributions * single statement, and for plain C that is accomplished by defining an 197*1031c584SApple OSS Distributions * anonymous enum and then separately typedef'ing the requested type name to the 198*1031c584SApple OSS Distributions * requested underlying integer type. So the type emitted actually has no 199*1031c584SApple OSS Distributions * relationship at all to the enum, and therefore while the compiler could 200*1031c584SApple OSS Distributions * enforce enum extensibility if you used the enum type, it cannot do so if you 201*1031c584SApple OSS Distributions * use the "_t" type resulting from this expression. 202*1031c584SApple OSS Distributions * 203*1031c584SApple OSS Distributions * But we still define a named enum type and decorate it appropriately for you, 204*1031c584SApple OSS Distributions * so if you really want the enum extensibility enforcement, you can use the 205*1031c584SApple OSS Distributions * enum type yourself, i.e. when compiling with a C compiler: 206*1031c584SApple OSS Distributions * 207*1031c584SApple OSS Distributions * OS_CLOSED_ENUM(my_type, uint64_t, 208*1031c584SApple OSS Distributions * FOO, 209*1031c584SApple OSS Distributions * BAR, 210*1031c584SApple OSS Distributions * BAZ, 211*1031c584SApple OSS Distributions * ); 212*1031c584SApple OSS Distributions * 213*1031c584SApple OSS Distributions * my_type_t mt = 98; // legal 214*1031c584SApple OSS Distributions * enum my_type emt = 98; // illegal 215*1031c584SApple OSS Distributions * 216*1031c584SApple OSS Distributions * But be aware that the underlying enum type's width is subject only to the C 217*1031c584SApple OSS Distributions * language's guarantees -- namely that it will be compatible with int, char, 218*1031c584SApple OSS Distributions * and unsigned char. It is not safe to rely on the size of this type. 219*1031c584SApple OSS Distributions * 220*1031c584SApple OSS Distributions * When compiling in ObjC or C++, both of the above assignments are illegal. 221*1031c584SApple OSS Distributions */ 222*1031c584SApple OSS Distributions #define __OS_ENUM_C_FALLBACK(_name, _type, ...) \ 223*1031c584SApple OSS Distributions typedef _type _name##_t; enum _name { __VA_ARGS__ } 224*1031c584SApple OSS Distributions 225*1031c584SApple OSS Distributions #define OS_ENUM(_name, _type, ...) \ 226*1031c584SApple OSS Distributions typedef _type _name##_t; enum { __VA_ARGS__ } 227*1031c584SApple OSS Distributions #define OS_CLOSED_ENUM(_name, _type, ...) \ 228*1031c584SApple OSS Distributions __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ 229*1031c584SApple OSS Distributions __OS_ENUM_ATTR_CLOSED 230*1031c584SApple OSS Distributions #define OS_OPTIONS(_name, _type, ...) \ 231*1031c584SApple OSS Distributions __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ 232*1031c584SApple OSS Distributions __OS_ENUM_ATTR __OS_OPTIONS_ATTR 233*1031c584SApple OSS Distributions #define OS_CLOSED_OPTIONS(_name, _type, ...) \ 234*1031c584SApple OSS Distributions __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ 235*1031c584SApple OSS Distributions __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR 236*1031c584SApple OSS Distributions #endif // __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) 237*1031c584SApple OSS Distributions 238*1031c584SApple OSS Distributions #if __has_feature(attribute_availability_swift) 239*1031c584SApple OSS Distributions // equivalent to __SWIFT_UNAVAILABLE from Availability.h 240*1031c584SApple OSS Distributions #define OS_SWIFT_UNAVAILABLE(_msg) \ 241*1031c584SApple OSS Distributions __attribute__((__availability__(swift, unavailable, message=_msg))) 242*1031c584SApple OSS Distributions #else 243*1031c584SApple OSS Distributions #define OS_SWIFT_UNAVAILABLE(_msg) 244*1031c584SApple OSS Distributions #endif 245*1031c584SApple OSS Distributions 246*1031c584SApple OSS Distributions #if __has_attribute(__swift_attr__) 247*1031c584SApple OSS Distributions #define OS_SWIFT_UNAVAILABLE_FROM_ASYNC(msg) \ 248*1031c584SApple OSS Distributions __attribute__((__swift_attr__("@_unavailableFromAsync(message: \"" msg "\")"))) 249*1031c584SApple OSS Distributions #else 250*1031c584SApple OSS Distributions #define OS_SWIFT_UNAVAILABLE_FROM_ASYNC(msg) 251*1031c584SApple OSS Distributions #endif 252*1031c584SApple OSS Distributions 253*1031c584SApple OSS Distributions #if __has_attribute(swift_private) 254*1031c584SApple OSS Distributions # define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__)) 255*1031c584SApple OSS Distributions #else 256*1031c584SApple OSS Distributions # define OS_REFINED_FOR_SWIFT 257*1031c584SApple OSS Distributions #endif 258*1031c584SApple OSS Distributions 259*1031c584SApple OSS Distributions #if __has_attribute(swift_name) 260*1031c584SApple OSS Distributions # define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) 261*1031c584SApple OSS Distributions #else 262*1031c584SApple OSS Distributions # define OS_SWIFT_NAME(_name) 263*1031c584SApple OSS Distributions #endif 264*1031c584SApple OSS Distributions 265*1031c584SApple OSS Distributions #define __OS_STRINGIFY(s) #s 266*1031c584SApple OSS Distributions #define OS_STRINGIFY(s) __OS_STRINGIFY(s) 267*1031c584SApple OSS Distributions #define __OS_CONCAT(x, y) x ## y 268*1031c584SApple OSS Distributions #define OS_CONCAT(x, y) __OS_CONCAT(x, y) 269*1031c584SApple OSS Distributions 270*1031c584SApple OSS Distributions #ifdef __GNUC__ 271*1031c584SApple OSS Distributions #define os_prevent_tail_call_optimization() __asm__("") 272*1031c584SApple OSS Distributions #define os_is_compile_time_constant(expr) __builtin_constant_p(expr) 273*1031c584SApple OSS Distributions #define os_compiler_barrier() __asm__ __volatile__("" ::: "memory") 274*1031c584SApple OSS Distributions #else 275*1031c584SApple OSS Distributions #define os_prevent_tail_call_optimization() do { } while (0) 276*1031c584SApple OSS Distributions #define os_is_compile_time_constant(expr) 0 277*1031c584SApple OSS Distributions #define os_compiler_barrier() do { } while (0) 278*1031c584SApple OSS Distributions #endif 279*1031c584SApple OSS Distributions 280*1031c584SApple OSS Distributions #if __has_attribute(not_tail_called) 281*1031c584SApple OSS Distributions #define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) 282*1031c584SApple OSS Distributions #else 283*1031c584SApple OSS Distributions #define OS_NOT_TAIL_CALLED 284*1031c584SApple OSS Distributions #endif 285*1031c584SApple OSS Distributions 286*1031c584SApple OSS Distributions #if KERNEL 287*1031c584SApple OSS Distributions /* 288*1031c584SApple OSS Distributions * LIBKERN_ALWAYS_DESTROY attribute can be applied to global variables with 289*1031c584SApple OSS Distributions * destructors. It specifies that and object should have its exit-time 290*1031c584SApple OSS Distributions * destructor run. This attribute is the default unless clang was invoked with 291*1031c584SApple OSS Distributions * -fno-c++-static-destructors. 292*1031c584SApple OSS Distributions */ 293*1031c584SApple OSS Distributions #if __has_attribute(always_destroy) 294*1031c584SApple OSS Distributions #define LIBKERN_ALWAYS_DESTROY __attribute__((__always_destroy__)) 295*1031c584SApple OSS Distributions #else 296*1031c584SApple OSS Distributions #define LIBKERN_ALWAYS_DESTROY 297*1031c584SApple OSS Distributions #endif 298*1031c584SApple OSS Distributions #endif 299*1031c584SApple OSS Distributions 300*1031c584SApple OSS Distributions typedef void (*os_function_t)(void *_Nullable); 301*1031c584SApple OSS Distributions 302*1031c584SApple OSS Distributions #ifdef __BLOCKS__ 303*1031c584SApple OSS Distributions /*! 304*1031c584SApple OSS Distributions * @typedef os_block_t 305*1031c584SApple OSS Distributions * 306*1031c584SApple OSS Distributions * @abstract 307*1031c584SApple OSS Distributions * Generic type for a block taking no arguments and returning no value. 308*1031c584SApple OSS Distributions * 309*1031c584SApple OSS Distributions * @discussion 310*1031c584SApple OSS Distributions * When not building with Objective-C ARC, a block object allocated on or 311*1031c584SApple OSS Distributions * copied to the heap must be released with a -[release] message or the 312*1031c584SApple OSS Distributions * Block_release() function. 313*1031c584SApple OSS Distributions * 314*1031c584SApple OSS Distributions * The declaration of a block literal allocates storage on the stack. 315*1031c584SApple OSS Distributions * Therefore, this is an invalid construct: 316*1031c584SApple OSS Distributions * <code> 317*1031c584SApple OSS Distributions * os_block_t block; 318*1031c584SApple OSS Distributions * if (x) { 319*1031c584SApple OSS Distributions * block = ^{ printf("true\n"); }; 320*1031c584SApple OSS Distributions * } else { 321*1031c584SApple OSS Distributions * block = ^{ printf("false\n"); }; 322*1031c584SApple OSS Distributions * } 323*1031c584SApple OSS Distributions * block(); // unsafe!!! 324*1031c584SApple OSS Distributions * </code> 325*1031c584SApple OSS Distributions * 326*1031c584SApple OSS Distributions * What is happening behind the scenes: 327*1031c584SApple OSS Distributions * <code> 328*1031c584SApple OSS Distributions * if (x) { 329*1031c584SApple OSS Distributions * struct Block __tmp_1 = ...; // setup details 330*1031c584SApple OSS Distributions * block = &__tmp_1; 331*1031c584SApple OSS Distributions * } else { 332*1031c584SApple OSS Distributions * struct Block __tmp_2 = ...; // setup details 333*1031c584SApple OSS Distributions * block = &__tmp_2; 334*1031c584SApple OSS Distributions * } 335*1031c584SApple OSS Distributions * </code> 336*1031c584SApple OSS Distributions * 337*1031c584SApple OSS Distributions * As the example demonstrates, the address of a stack variable is escaping the 338*1031c584SApple OSS Distributions * scope in which it is allocated. That is a classic C bug. 339*1031c584SApple OSS Distributions * 340*1031c584SApple OSS Distributions * Instead, the block literal must be copied to the heap with the Block_copy() 341*1031c584SApple OSS Distributions * function or by sending it a -[copy] message. 342*1031c584SApple OSS Distributions */ 343*1031c584SApple OSS Distributions typedef void (^os_block_t)(void); 344*1031c584SApple OSS Distributions #endif 345*1031c584SApple OSS Distributions 346*1031c584SApple OSS Distributions #if KERNEL 347*1031c584SApple OSS Distributions #if __has_feature(ptrauth_calls) 348*1031c584SApple OSS Distributions #include <ptrauth.h> 349*1031c584SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR(type) __ptrauth(ptrauth_key_process_independent_data, 1, ptrauth_string_discriminator(type)) 350*1031c584SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR_AUTH_NULL(type) __ptrauth(ptrauth_key_process_independent_data, 1, ptrauth_string_discriminator(type), "authenticates-null-values") 351*1031c584SApple OSS Distributions #define OS_PTRAUTH_DISCRIMINATOR(str) ptrauth_string_discriminator(str) 352*1031c584SApple OSS Distributions #define __ptrauth_only 353*1031c584SApple OSS Distributions #else // __has_feature(ptrauth_calls) 354*1031c584SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR(type) 355*1031c584SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR_AUTH_NULL(type) 356*1031c584SApple OSS Distributions #define OS_PTRAUTH_DISCRIMINATOR(str) 0 357*1031c584SApple OSS Distributions #define __ptrauth_only __unused 358*1031c584SApple OSS Distributions #endif // __has_feature(ptrauth_calls) 359*1031c584SApple OSS Distributions #endif // KERNEL 360*1031c584SApple OSS Distributions 361*1031c584SApple OSS Distributions #if KERNEL 362*1031c584SApple OSS Distributions #if __has_feature(ptrauth_calls) 363*1031c584SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_FUNCTION_PTR(type) \ 364*1031c584SApple OSS Distributions __ptrauth(ptrauth_key_function_pointer, 1, ptrauth_string_discriminator(type)) 365*1031c584SApple OSS Distributions #else 366*1031c584SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_FUNCTION_PTR(type) 367*1031c584SApple OSS Distributions #endif 368*1031c584SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_PTR OS_PTRAUTH_SIGNED_PTR 369*1031c584SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_PTR_AUTH_NULL OS_PTRAUTH_SIGNED_PTR_AUTH_NULL 370*1031c584SApple OSS Distributions #endif // KERNEL 371*1031c584SApple OSS Distributions 372*1031c584SApple OSS Distributions #define OS_ASSUME_PTR_ABI_SINGLE_BEGIN __ASSUME_PTR_ABI_SINGLE_BEGIN 373*1031c584SApple OSS Distributions #define OS_ASSUME_PTR_ABI_SINGLE_END __ASSUME_PTR_ABI_SINGLE_END 374*1031c584SApple OSS Distributions #define OS_UNSAFE_INDEXABLE __unsafe_indexable 375*1031c584SApple OSS Distributions #define OS_HEADER_INDEXABLE __header_indexable 376*1031c584SApple OSS Distributions #define OS_COUNTED_BY(N) __counted_by(N) 377*1031c584SApple OSS Distributions #define OS_SIZED_BY(N) __sized_by(N) 378*1031c584SApple OSS Distributions 379*1031c584SApple OSS Distributions #endif // __OS_BASE__ 380