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