1================== 2Source Annotations 3================== 4 5The Clang frontend supports several source-level annotations in the form of 6`GCC-style attributes <https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html>`_ 7and pragmas that can help make using the Clang Static Analyzer more useful. 8These annotations can both help suppress false positives as well as enhance the 9analyzer's ability to find bugs. 10 11This page gives a practical overview of such annotations. For more technical 12specifics regarding Clang-specific annotations please see the Clang's list of 13`language extensions <https://clang.llvm.org/docs/LanguageExtensions.html>`_. 14Details of "standard" GCC attributes (that Clang also supports) can 15be found in the `GCC manual <https://gcc.gnu.org/onlinedocs/gcc/>`_, with the 16majority of the relevant attributes being in the section on 17`function attributes <https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_. 18 19Note that attributes that are labeled **Clang-specific** are not 20recognized by GCC. Their use can be conditioned using preprocessor macros 21(examples included on this page). 22 23.. contents:: 24 :local: 25 26Annotations to Enhance Generic Checks 27_____________________________________ 28 29Null Pointer Checking 30##################### 31 32Attribute 'nonnull' 33------------------- 34 35The analyzer recognizes the GCC attribute 'nonnull', which indicates that a 36function expects that a given function parameter is not a null pointer. 37Specific details of the syntax of using the 'nonnull' attribute can be found in 38`GCC's documentation <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-nonnull-function-attribute>`_. 39 40Both the Clang compiler and GCC will flag warnings for simple cases where a 41null pointer is directly being passed to a function with a 'nonnull' parameter 42(e.g., as a constant). The analyzer extends this checking by using its deeper 43symbolic analysis to track what pointer values are potentially null and then 44flag warnings when they are passed in a function call via a 'nonnull' 45parameter. 46 47**Example** 48 49.. code-block:: c 50 51 int bar(int*p, int q, int *r) __attribute__((nonnull(1,3))); 52 53 int foo(int *p, int *q) { 54 return !p ? bar(q, 2, p) 55 : bar(p, 2, q); 56 } 57 58Running ``scan-build`` over this source produces the following output: 59 60.. image:: ../images/example_attribute_nonnull.png 61 62.. _custom_assertion_handlers: 63 64Custom Assertion Handlers 65######################### 66 67The analyzer exploits code assertions by pruning off paths where the 68assertion condition is false. The idea is capture any program invariants 69specified in the assertion that the developer may know but is not immediately 70apparent in the code itself. In this way assertions make implicit assumptions 71explicit in the code, which not only makes the analyzer more accurate when 72finding bugs, but can help others better able to understand your code as well. 73It can also help remove certain kinds of analyzer false positives by pruning off 74false paths. 75 76In order to exploit assertions, however, the analyzer must understand when it 77encounters an "assertion handler". Typically assertions are 78implemented with a macro, with the macro performing a check for the assertion 79condition and, when the check fails, calling an assertion handler. For 80example, consider the following code fragment: 81 82.. code-block: c 83 84 void foo(int *p) { 85 assert(p != NULL); 86 } 87 88When this code is preprocessed on Mac OS X it expands to the following: 89 90.. code-block: c 91 92 void foo(int *p) { 93 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0); 94 } 95 96In this example, the assertion handler is ``__assert_rtn``. When called, 97most assertion handlers typically print an error and terminate the program. The 98analyzer can exploit such semantics by ending the analysis of a path once it 99hits a call to an assertion handler. 100 101The trick, however, is that the analyzer needs to know that a called function 102is an assertion handler; otherwise the analyzer might assume the function call 103returns and it will continue analyzing the path where the assertion condition 104failed. This can lead to false positives, as the assertion condition usually 105implies a safety condition (e.g., a pointer is not null) prior to performing 106some action that depends on that condition (e.g., dereferencing a pointer). 107 108The analyzer knows about several well-known assertion handlers, but can 109automatically infer if a function should be treated as an assertion handler if 110it is annotated with the 'noreturn' attribute or the (Clang-specific) 111'analyzer_noreturn' attribute. Note that, currently, clang does not support 112these attributes on Objective-C methods and C++ methods. 113 114Attribute 'noreturn' 115-------------------- 116 117The 'noreturn' attribute is a GCC attribute that can be placed on the 118declarations of functions. It means exactly what its name implies: a function 119with a 'noreturn' attribute should never return. 120 121Specific details of the syntax of using the 'noreturn' attribute can be found 122in `GCC's documentation <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute>`__. 123 124Not only does the analyzer exploit this information when pruning false paths, 125but the compiler also takes it seriously and will generate different code (and 126possibly better optimized) under the assumption that the function does not 127return. 128 129**Example** 130 131On Mac OS X, the function prototype for ``__assert_rtn`` (declared in 132``assert.h``) is specifically annotated with the 'noreturn' attribute: 133 134.. code-block: c 135 136 void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__)); 137 138Attribute 'analyzer_noreturn' (Clang-specific) 139---------------------------------------------- 140 141The Clang-specific 'analyzer_noreturn' attribute is almost identical to 142'noreturn' except that it is ignored by the compiler for the purposes of code 143generation. 144 145This attribute is useful for annotating assertion handlers that actually 146*can* return, but for the purpose of using the analyzer we want to 147pretend that such functions do not return. 148 149Because this attribute is Clang-specific, its use should be conditioned with 150the use of preprocessor macros. 151 152**Example** 153 154.. code-block: c 155 156 #ifndef CLANG_ANALYZER_NORETURN 157 #if __has_feature(attribute_analyzer_noreturn) 158 #define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) 159 #else 160 #define CLANG_ANALYZER_NORETURN 161 #endif 162 #endif 163 164 void my_assert_rtn(const char *, const char *, int, const char *) CLANG_ANALYZER_NORETURN; 165 166Mac OS X API Annotations 167________________________ 168 169.. _cocoa_mem: 170 171Cocoa & Core Foundation Memory Management Annotations 172##################################################### 173 174The analyzer supports the proper management of retain counts for 175both Cocoa and Core Foundation objects. This checking is largely based on 176enforcing Cocoa and Core Foundation naming conventions for Objective-C methods 177(Cocoa) and C functions (Core Foundation). Not strictly following these 178conventions can cause the analyzer to miss bugs or flag false positives. 179 180One can educate the analyzer (and others who read your code) about methods or 181functions that deviate from the Cocoa and Core Foundation conventions using the 182attributes described here. However, you should consider using proper naming 183conventions or the `objc_method_family <https://clang.llvm.org/docs/LanguageExtensions.html#the-objc-method-family-attribute>`_ 184attribute, if applicable. 185 186.. _ns_returns_retained: 187 188Attribute 'ns_returns_retained' (Clang-specific) 189------------------------------------------------ 190 191The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to 192annotate an Objective-C method or C function as returning a retained Cocoa 193object that the caller is responsible for releasing (via sending a 194``release`` message to the object). The Foundation framework defines a 195macro ``NS_RETURNS_RETAINED`` that is functionally equivalent to the 196one shown below. 197 198**Placing on Objective-C methods**: For Objective-C methods, this 199annotation essentially tells the analyzer to treat the method as if its name 200begins with "alloc" or "new" or contains the word 201"copy". 202 203**Placing on C functions**: For C functions returning Cocoa objects, the 204analyzer typically does not make any assumptions about whether or not the object 205is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C 206functions allows the analyzer to perform extra checking. 207 208**Example** 209 210.. code-block: objc 211 212 #import <Foundation/Foundation.h>; 213 214 #ifndef __has_feature // Optional. 215 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 216 #endif 217 218 #ifndef NS_RETURNS_RETAINED 219 #if __has_feature(attribute_ns_returns_retained) 220 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) 221 #else 222 #define NS_RETURNS_RETAINED 223 #endif 224 #endif 225 226 @interface MyClass : NSObject {} 227 - (NSString*) returnsRetained NS_RETURNS_RETAINED; 228 - (NSString*) alsoReturnsRetained; 229 @end 230 231 @implementation MyClass 232 - (NSString*) returnsRetained { 233 return [[NSString alloc] initWithCString:"no leak here"]; 234 } 235 - (NSString*) alsoReturnsRetained { 236 return [[NSString alloc] initWithCString:"flag a leak"]; 237 } 238 @end 239 240Running ``scan-build`` on this source file produces the following output: 241 242.. image:: ../images/example_ns_returns_retained.png 243 244.. _ns_returns_not_retained: 245 246Attribute 'ns_returns_not_retained' (Clang-specific) 247---------------------------------------------------- 248 249The 'ns_returns_not_retained' attribute is the complement of 250'`ns_returns_retained`_'. Where a function or method may appear to obey the 251Cocoa conventions and return a retained Cocoa object, this attribute can be 252used to indicate that the object reference returned should not be considered as 253an "owning" reference being returned to the caller. The Foundation 254framework defines a macro ``NS_RETURNS_NOT_RETAINED`` that is functionally 255equivalent to the one shown below. 256 257Usage is identical to `ns_returns_retained`_. When using the 258attribute, be sure to declare it within the proper macro that checks for 259its availability, as it is not available in earlier versions of the analyzer: 260 261.. code-block:objc 262 263 #ifndef __has_feature // Optional. 264 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 265 #endif 266 267 #ifndef NS_RETURNS_NOT_RETAINED 268 #if __has_feature(attribute_ns_returns_not_retained) 269 #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) 270 #else 271 #define NS_RETURNS_NOT_RETAINED 272 #endif 273 #endif 274 275.. _cf_returns_retained: 276 277Attribute 'cf_returns_retained' (Clang-specific) 278------------------------------------------------ 279 280The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to 281annotate an Objective-C method or C function as returning a retained Core 282Foundation object that the caller is responsible for releasing. The 283CoreFoundation framework defines a macro ``CF_RETURNS_RETAINED`` that is 284functionally equivalent to the one shown below. 285 286**Placing on Objective-C methods**: With respect to Objective-C methods., 287this attribute is identical in its behavior and usage to 'ns_returns_retained' 288except for the distinction of returning a Core Foundation object instead of a 289Cocoa object. 290 291This distinction is important for the following reason: as Core Foundation is a 292C API, the analyzer cannot always tell that a pointer return value refers to a 293Core Foundation object. In contrast, it is trivial for the analyzer to 294recognize if a pointer refers to a Cocoa object (given the Objective-C type 295system). 296 297**Placing on C functions**: When placing the attribute 298'cf_returns_retained' on the declarations of C functions, the analyzer 299interprets the function as: 300 3011. Returning a Core Foundation Object 3022. Treating the function as if it its name contained the keywords 303 "create" or "copy". This means the returned object as a 304 +1 retain count that must be released by the caller, either by sending a 305 ``release`` message (via toll-free bridging to an Objective-C object 306 pointer), or calling ``CFRelease`` or a similar function. 307 308**Example** 309 310.. code-block:objc 311 312 #import <Cocoa/Cocoa.h> 313 314 #ifndef __has_feature // Optional. 315 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 316 #endif 317 318 #ifndef CF_RETURNS_RETAINED 319 #if __has_feature(attribute_cf_returns_retained) 320 #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) 321 #else 322 #define CF_RETURNS_RETAINED 323 #endif 324 #endif 325 326 @interface MyClass : NSObject {} 327 - (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; 328 - (NSDate*) alsoReturnsRetained; 329 - (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; 330 @end 331 332 CF_RETURNS_RETAINED 333 CFDateRef returnsRetainedCFDate() { 334 return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 335 } 336 337 @implementation MyClass 338 - (NSDate*) returnsCFRetained { 339 return (NSDate*) returnsRetainedCFDate(); // No leak. 340 } 341 342 - (NSDate*) alsoReturnsRetained { 343 return (NSDate*) returnsRetainedCFDate(); // Always report a leak. 344 } 345 346 - (NSDate*) returnsNSRetained { 347 return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC. 348 } 349 @end 350 351Running ``scan-build`` on this example produces the following output: 352 353.. image:: ../images/example_cf_returns_retained.png 354 355Attribute 'cf_returns_not_retained' (Clang-specific) 356---------------------------------------------------- 357 358The 'cf_returns_not_retained' attribute is the complement of 359'`cf_returns_retained`_'. Where a function or method may appear to obey the 360Core Foundation or Cocoa conventions and return a retained Core Foundation 361object, this attribute can be used to indicate that the object reference 362returned should not be considered as an "owning" reference being 363returned to the caller. The CoreFoundation framework defines a macro 364**``CF_RETURNS_NOT_RETAINED``** that is functionally equivalent to the one 365shown below. 366 367Usage is identical to cf_returns_retained_. When using the attribute, be sure 368to declare it within the proper macro that checks for its availability, as it 369is not available in earlier versions of the analyzer: 370 371.. code-block:objc 372 373 #ifndef __has_feature // Optional. 374 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 375 #endif 376 377 #ifndef CF_RETURNS_NOT_RETAINED 378 #if __has_feature(attribute_cf_returns_not_retained) 379 #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) 380 #else 381 #define CF_RETURNS_NOT_RETAINED 382 #endif 383 #endif 384 385.. _ns_consumed: 386 387Attribute 'ns_consumed' (Clang-specific) 388---------------------------------------- 389 390The 'ns_consumed' attribute can be placed on a specific parameter in either 391the declaration of a function or an Objective-C method. It indicates to the 392static analyzer that a ``release`` message is implicitly sent to the 393parameter upon completion of the call to the given function or method. The 394Foundation framework defines a macro ``NS_RELEASES_ARGUMENT`` that 395is functionally equivalent to the ``NS_CONSUMED`` macro shown below. 396 397**Example** 398 399.. code-block:objc 400 401 #ifndef __has_feature // Optional. 402 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 403 #endif 404 405 #ifndef NS_CONSUMED 406 #if __has_feature(attribute_ns_consumed) 407 #define NS_CONSUMED __attribute__((ns_consumed)) 408 #else 409 #define NS_CONSUMED 410 #endif 411 #endif 412 413 void consume_ns(id NS_CONSUMED x); 414 415 void test() { 416 id x = [[NSObject alloc] init]; 417 consume_ns(x); // No leak! 418 } 419 420 @interface Foo : NSObject 421 + (void) releaseArg:(id) NS_CONSUMED x; 422 + (void) releaseSecondArg:(id)x second:(id) NS_CONSUMED y; 423 @end 424 425 void test_method() { 426 id x = [[NSObject alloc] init]; 427 [Foo releaseArg:x]; // No leak! 428 } 429 430 void test_method2() { 431 id a = [[NSObject alloc] init]; 432 id b = [[NSObject alloc] init]; 433 [Foo releaseSecondArg:a second:b]; // 'a' is leaked, but 'b' is released. 434 } 435 436Attribute 'cf_consumed' (Clang-specific) 437---------------------------------------- 438 439The 'cf_consumed' attribute is practically identical to ns_consumed_. The 440attribute can be placed on a specific parameter in either the declaration of a 441function or an Objective-C method. It indicates to the static analyzer that the 442object reference is implicitly passed to a call to ``CFRelease`` upon 443completion of the call to the given function or method. The CoreFoundation 444framework defines a macro ``CF_RELEASES_ARGUMENT`` that is functionally 445equivalent to the ``CF_CONSUMED`` macro shown below. 446 447Operationally this attribute is nearly identical to 'ns_consumed'. 448 449**Example** 450 451.. code-block:objc 452 453 #ifndef __has_feature // Optional. 454 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 455 #endif 456 457 #ifndef CF_CONSUMED 458 #if __has_feature(attribute_cf_consumed) 459 #define CF_CONSUMED __attribute__((cf_consumed)) 460 #else 461 #define CF_CONSUMED 462 #endif 463 #endif 464 465 void consume_cf(id CF_CONSUMED x); 466 void consume_CFDate(CFDateRef CF_CONSUMED x); 467 468 void test() { 469 id x = [[NSObject alloc] init]; 470 consume_cf(x); // No leak! 471 } 472 473 void test2() { 474 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 475 consume_CFDate(date); // No leak, including under GC! 476 477 } 478 479 @interface Foo : NSObject 480 + (void) releaseArg:(CFDateRef) CF_CONSUMED x; 481 @end 482 483 void test_method() { 484 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 485 [Foo releaseArg:date]; // No leak! 486 } 487 488.. _ns_consumes_self: 489 490Attribute 'ns_consumes_self' (Clang-specific) 491--------------------------------------------- 492 493The 'ns_consumes_self' attribute can be placed only on an Objective-C method 494declaration. It indicates that the receiver of the message is 495"consumed" (a single reference count decremented) after the message 496is sent. This matches the semantics of all "init" methods. 497 498One use of this attribute is declare your own init-like methods that do not 499follow the standard Cocoa naming conventions. 500 501**Example** 502 503.. code-block:objc 504 #ifndef __has_feature 505 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 506 #endif 507 508 #ifndef NS_CONSUMES_SELF 509 #if __has_feature((attribute_ns_consumes_self)) 510 #define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) 511 #else 512 #define NS_CONSUMES_SELF 513 #endif 514 #endif 515 516 @interface MyClass : NSObject 517 - initWith:(MyClass *)x; 518 - nonstandardInitWith:(MyClass *)x NS_CONSUMES_SELF NS_RETURNS_RETAINED; 519 @end 520 521In this example, ``-nonstandardInitWith:`` has the same ownership 522semantics as the init method ``-initWith:``. The static analyzer will 523observe that the method consumes the receiver, and then returns an object with 524a +1 retain count. 525 526The Foundation framework defines a macro ``NS_REPLACES_RECEIVER`` which is 527functionally equivalent to the combination of ``NS_CONSUMES_SELF`` and 528``NS_RETURNS_RETAINED`` shown above. 529 530Libkern Memory Management Annotations 531##################################### 532 533`Libkern <https://developer.apple.com/documentation/kernel/osobject?language=objc>`_ 534requires developers to inherit all heap allocated objects from ``OSObject`` and 535to perform manual reference counting. The reference counting model is very 536similar to MRR (manual retain-release) mode in 537`Objective-C <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>`_ 538or to CoreFoundation reference counting. 539Freshly-allocated objects start with a reference count of 1, and calls to 540``retain`` increment it, while calls to ``release`` decrement it. The object is 541deallocated whenever its reference count reaches zero. 542 543Manually incrementing and decrementing reference counts is error-prone: 544over-retains lead to leaks, and over-releases lead to uses-after-free. 545The analyzer can help the programmer to check for unbalanced 546retain/release calls. 547 548The reference count checking is based on the principle of *locality*: it should 549be possible to establish correctness (lack of leaks/uses after free) by looking 550at each function body, and the declarations (not the definitions) of all the 551functions it interacts with. 552 553In order to support such reasoning, it should be possible to *summarize* the 554behavior of each function, with respect to reference count of its returned 555values and attributes. 556 557By default, the following summaries are assumed: 558 559- All functions starting with ``get`` or ``Get``, unless they are returning 560 subclasses of ``OSIterator``, are assumed to be returning at +0. That is, the 561 caller has no reference count *obligations* with respect to the reference 562 count of the returned object and should leave it untouched. 563 564- All other functions are assumed to return at +1. That is, the caller has an 565 *obligation* to release such objects. 566 567- Functions are assumed not to change the reference count of their parameters, 568 including the implicit ``this`` parameter. 569 570These summaries can be overriden with the following 571`attributes <https://clang.llvm.org/docs/AttributeReference.html#os-returns-not-retained>`_: 572 573Attribute 'os_returns_retained' 574------------------------------- 575 576The ``os_returns_retained`` attribute (accessed through the macro 577``LIBKERN_RETURNS_RETAINED``) plays a role identical to `ns_returns_retained`_ 578for functions returning ``OSObject`` subclasses. The attribute indicates that 579it is a callers responsibility to release the returned object. 580 581Attribute 'os_returns_not_retained' 582----------------------------------- 583 584The ``os_returns_not_retained`` attribute (accessed through the macro 585``LIBKERN_RETURNS_NOT_RETAINED``) plays a role identical to 586`ns_returns_not_retained`_ for functions returning ``OSObject`` subclasses. The 587attribute indicates that the caller should not change the retain count of the 588returned object. 589 590 591**Example** 592 593.. code-block:objc 594 595 class MyClass { 596 OSObject *f; 597 LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter(); 598 } 599 600 601 // Note that the annotation only has to be applied to the function declaration. 602 OSObject * MyClass::myFieldGetter() { 603 return f; 604 } 605 606Attribute 'os_consumed' 607----------------------- 608 609Similarly to `ns_consumed`_ attribute, ``os_consumed`` (accessed through 610``LIBKERN_CONSUMED``) attribute, applied to a parameter, indicates that the 611call to the function *consumes* the parameter: the callee should either release 612it or store it and release it in the destructor, while the caller should assume 613one is subtracted from the reference count after the call. 614 615.. code-block:objc 616 IOReturn addToList(LIBKERN_CONSUMED IOPMinformee *newInformee); 617 618Attribute 'os_consumes_this' 619---------------------------- 620 621Similarly to `ns_consumes_self`_, the ``os_consumes_self`` attribute indicates 622that the method call *consumes* the implicit ``this`` argument: the caller 623should assume one was subtracted from the reference count of the object after 624the call, and the callee has on obligation to either release the argument, or 625store it and eventually release it in the destructor. 626 627 628.. code-block:objc 629 void addThisToList(OSArray *givenList) LIBKERN_CONSUMES_THIS; 630 631Out Parameters 632-------------- 633 634A function can also return an object to a caller by a means of an out parameter 635(a pointer-to-OSObject-pointer is passed, and a callee writes a pointer to an 636object into an argument). Currently the analyzer does not track unannotated out 637parameters by default, but with annotations we distinguish four separate cases: 638 639**1. Non-retained out parameters**, identified using 640``LIBKERN_RETURNS_NOT_RETAINED`` applied to parameters, e.g.: 641 642.. code-block:objc 643 void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj) 644 645Such functions write a non-retained object into an out parameter, and the 646caller has no further obligations. 647 648**2. Retained out parameters**, identified using ``LIBKERN_RETURNS_RETAINED``: 649 650.. code-block:objc 651 void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj) 652 653In such cases a retained object is written into an out parameter, which the caller has then to release in order to avoid a leak. 654 655These two cases are simple - but in practice a functions returning an 656out-parameter usually also return a return code, and then an out parameter may 657or may not be written, which conditionally depends on the exit code, e.g.: 658 659.. code-block:objc 660 bool maybeCreateObject(LIBKERN_RETURNS_RETAINED OSObject **obj); 661 662For such functions, the usual semantics is that an object is written into on "success", and not written into on "failure". 663 664For ``LIBKERN_RETURNS_RETAINED`` we assume the following definition of 665success: 666 667- For functions returning ``OSReturn`` or ``IOReturn`` (any typedef to 668 ``kern_return_t``) success is defined as having an output of zero 669 (``kIOReturnSuccess`` is zero). 670 671- For all others, success is non-zero (e.g. non-nullptr for pointers) 672 673**3. Retained out parameters on zero return** The annotation 674``LIBKERN_RETURNS_RETAINED_ON_ZERO`` states that a retained object is written 675into if and only if the function returns a zero value: 676 677.. code-block:objc 678 bool OSUnserializeXML(void *data, LIBKERN_RETURNS_RETAINED_ON_ZERO OSString **errString); 679 680Then the caller has to release an object if the function has returned zero. 681 682**4. Retained out parameters on non-zero return** Similarly, 683``LIBKERN_RETURNS_RETAINED_ON_NONZERO`` specifies that a retained object is 684written into the parameter if and only if the function has returned a non-zero 685value. 686 687Note that for non-retained out parameters conditionals do not matter, as the 688caller has no obligations regardless of whether an object is written into or 689not. 690