xref: /llvm-project/clang/docs/analyzer/user-docs/Annotations.rst (revision 21e58ee9f7de60a7e9202ad3f424ec3ad5a6fce5)
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