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="http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html">GCC-style 21 attributes</a> and pragmas that can help make using the Clang Static Analyzer 22 more useful. These annotations can both help suppress false positives as well as 23 enhance the analyzer's ability to find bugs.</p> 24 25 <p>This page gives a practical overview of such annotations. For more technical 26 specifics regarding Clang-specific annotations please see the Clang's list of <a 27 href="http://clang.llvm.org/docs/LanguageExtensions.html">language 28 extensions</a>. Details of "standard" GCC attributes (that Clang also 29 supports) can be found in the <a href="http://gcc.gnu.org/onlinedocs/gcc/">GCC 30 manual</a>, with the majority of the relevant attributes being in the section on 31 <a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html">function 32 attributes</a>.</p> 33 34 <p>Note that attributes that are labeled <b>Clang-specific</b> are not 35 recognized 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 </ul> 64 </li> 65 <li><a href="#custom_assertions">Custom Assertion Handlers</a> 66 <ul> 67 <li><a href="#attr_noreturn">Attribute 'noreturn'</a></li> 68 <li><a href="#attr_analyzer_noreturn">Attribute 'analyzer_noreturn'</a></li> 69 </ul> 70 </li> 71 </ul> 72 73 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 74 <h2 id="generic">Annotations to Enhance Generic Checks</h2> 75 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 76 77 <h3 id="null_checking">Null Pointer Checking</h3> 78 79 <h4 id="attr_nonnull">Attribute 'nonnull'</h4> 80 81 <p>The analyzer recognizes the GCC attribute 'nonnull', which indicates that a 82 function expects that a given function parameter is not a null pointer. Specific 83 details of the syntax of using the 'nonnull' attribute can be found in <a 84 href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-2263">GCC's 85 documentation</a>.</p> 86 87 <p>Both the Clang compiler and GCC will flag warnings for simple cases where a 88 null pointer is directly being passed to a function with a 'nonnull' parameter 89 (e.g., as a constant). The analyzer extends this checking by using its deeper 90 symbolic analysis to track what pointer values are potentially null and then 91 flag warnings when they are passed in a function call via a 'nonnull' 92 parameter.</p> 93 94 <p><b>Example</b></p> 95 96 <pre class="code_example"> 97 <span class="command">$ cat test.m</span> 98 int bar(int*p, int q, int *r) __attribute__((nonnull(1,3))); 99 100 int foo(int *p, int *q) { 101 return !p ? bar(q, 2, p) 102 : bar(p, 2, q); 103 } 104 </pre> 105 106 <p>Running <tt>scan-build</tt> over this source produces the following 107 output:</p> 108 109 <img src="images/example_attribute_nonnull.png" alt="example attribute nonnull"> 110 111 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 112 <h2 id="macosx">Mac OS X API Annotations</h2> 113 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 114 115 <h3 id="cocoa_mem">Cocoa & Core Foundation Memory Management 116 Annotations</h3> 117 118 <!-- 119 <p>As described in <a href="/available_checks.html#retain_release">Available 120 Checks</a>, 121 --> 122 <p>The analyzer supports the proper management of retain counts for 123 both Cocoa and Core Foundation objects. This checking is largely based on 124 enforcing Cocoa and Core Foundation naming conventions for Objective-C methods 125 (Cocoa) and C functions (Core Foundation). Not strictly following these 126 conventions can cause the analyzer to miss bugs or flag false positives.</p> 127 128 <p>One can educate the analyzer (and others who read your code) about methods or 129 functions that deviate from the Cocoa and Core Foundation conventions using the 130 attributes described here. However, you should consider using proper naming 131 conventions or the <a 132 href="http://clang.llvm.org/docs/LanguageExtensions.html#the-objc-method-family-attribute"><tt>objc_method_family</tt></a> 133 attribute, if applicable.</p> 134 135 <h4 id="attr_ns_returns_retained">Attribute 'ns_returns_retained' 136 (Clang-specific)</h4> 137 138 <p>The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to 139 annotate an Objective-C method or C function as returning a retained Cocoa 140 object that the caller is responsible for releasing (via sending a 141 <tt>release</tt> message to the object). The Foundation framework defines a 142 macro <b><tt>NS_RETURNS_RETAINED</tt></b> that is functionally equivalent to the 143 one shown below.</p> 144 145 <p><b>Placing on Objective-C methods</b>: For Objective-C methods, this 146 annotation essentially tells the analyzer to treat the method as if its name 147 begins with "alloc" or "new" or contains the word 148 "copy".</p> 149 150 <p><b>Placing on C functions</b>: For C functions returning Cocoa objects, the 151 analyzer typically does not make any assumptions about whether or not the object 152 is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C 153 functions allows the analyzer to perform extra checking.</p> 154 155 <p><b>Important note when using Garbage Collection</b>: Note that the analyzer 156 interprets this attribute slightly differently when using Objective-C garbage 157 collection (available on Mac OS 10.5+). When analyzing Cocoa code that uses 158 garbage collection, "alloc" methods are assumed to return an object 159 that is managed by the garbage collector (and thus doesn't have a retain count 160 the caller must balance). These same assumptions are applied to methods or 161 functions annotated with 'ns_returns_retained'. If you are returning a Core 162 Foundation object (which may not be managed by the garbage collector) you should 163 use 'cf_returns_retained'.</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 206 href="#attr_ns_returns_retained">ns_returns_retained</a>'. Where a function or 207 method may appear to obey the Cocoa conventions and return a retained Cocoa 208 object, this attribute can be used to indicate that the object reference 209 returned should not be considered as an "owning" reference being 210 returned to the caller. The Foundation framework defines a 211 macro <b><tt>NS_RETURNS_NOT_RETAINED</tt></b> that is functionally equivalent to 212 the one shown below.</p> 213 214 <p>Usage is identical to <a 215 href="#attr_ns_returns_retained">ns_returns_retained</a>. When using the 216 attribute, be sure to declare it within the proper macro that checks for 217 its 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 238 annotate an Objective-C method or C function as returning a retained Core 239 Foundation object that the caller is responsible for releasing. The 240 CoreFoundation framework defines a macro <b><tt>CF_RETURNS_RETAINED</tt></b> 241 that 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., 244 this attribute is identical in its behavior and usage to 'ns_returns_retained' 245 except for the distinction of returning a Core Foundation object instead of a 246 Cocoa object. This distinction is important for two reasons:</p> 247 248 <ul> 249 <li>Core Foundation objects are not automatically managed by the Objective-C 250 garbage collector.</li> 251 <li>Because Core Foundation is a C API, the analyzer cannot always tell that a 252 pointer return value refers to a Core Foundation object. In contrast, it is 253 trivial for the analyzer to recognize if a pointer refers to a Cocoa object 254 (given the Objective-C type system). 255 </ul> 256 257 <p><b>Placing on C functions</b>: When placing the attribute 258 'cf_returns_retained' on the declarations of C functions, the analyzer 259 interprets the function as:</p> 260 261 <ol> 262 <li>Returning a Core Foundation Object</li> 263 <li>Treating the function as if it its name 264 contained the keywords "create" or "copy". This means the 265 returned object as a +1 retain count that must be released by the caller, either 266 by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C 267 object pointer), calling <tt>CFRelease</tt> (or similar function), or using 268 <tt>CFMakeCollectable</tt> to register the object with the Objective-C garbage 269 collector.</li> 270 </ol> 271 272 <p><b>Example</b></p> 273 274 <p>In this example, observe the difference in output when the code is compiled 275 to not use garbage collection versus when it is compiled to only use garbage 276 collection (<tt>-fobjc-gc-only</tt>).</p> 277 278 <pre class="code_example"> 279 <span class="command">$ cat test.m</span> 280 $ cat test.m 281 #import <Cocoa/Cocoa.h> 282 283 #ifndef __has_feature // Optional. 284 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 285 #endif 286 287 #ifndef CF_RETURNS_RETAINED 288 #if __has_feature(attribute_cf_returns_retained) 289 <span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span> 290 #else 291 #define CF_RETURNS_RETAINED 292 #endif 293 #endif 294 295 @interface MyClass : NSObject {} 296 - (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>; 297 - (NSDate*) alsoReturnsRetained; 298 - (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>; 299 @end 300 301 <span class="code_highlight">CF_RETURNS_RETAINED</span> 302 CFDateRef returnsRetainedCFDate() { 303 return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 304 } 305 306 @implementation MyClass 307 - (NSDate*) returnsCFRetained { 308 return (NSDate*) returnsRetainedCFDate(); <b><i>// No leak.</i></b> 309 } 310 311 - (NSDate*) alsoReturnsRetained { 312 return (NSDate*) returnsRetainedCFDate(); <b><i>// Always report a leak.</i></b> 313 } 314 315 - (NSDate*) returnsNSRetained { 316 return (NSDate*) returnsRetainedCFDate(); <b><i>// Report a leak when using GC.</i></b> 317 } 318 @end 319 </pre> 320 321 <p>Running <tt>scan-build</tt> on this example produces the following output:</p> 322 323 <img src="images/example_cf_returns_retained.png" alt="example returns retained"> 324 325 <p>When the above code is compiled using Objective-C garbage collection (i.e., 326 code is compiled with the flag <tt>-fobjc-gc</tt> or <tt>-fobjc-gc-only</tt>), 327 <tt>scan-build</tt> produces both the above error (with slightly different text 328 to indicate the code uses garbage collection) as well as the following warning, 329 which indicates a leak that occurs <em>only</em> when using garbage 330 collection:</p> 331 332 <img src="images/example_cf_returns_retained_gc.png" alt="example returns retained gc"> 333 334 <h4 id="attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained' 335 (Clang-specific)</h4> 336 337 <p>The 'cf_returns_not_retained' attribute is the complement of '<a 338 href="#attr_cf_returns_retained">cf_returns_retained</a>'. Where a function or 339 method may appear to obey the Core Foundation or Cocoa conventions and return 340 a retained Core Foundation object, this attribute can be used to indicate that 341 the object reference returned should not be considered as an 342 "owning" reference being returned to the caller. The 343 CoreFoundation framework defines a macro <b><tt>CF_RETURNS_NOT_RETAINED</tt></b> 344 that is functionally equivalent to the one shown below.</p> 345 346 <p>Usage is identical to <a 347 href="#attr_cf_returns_retained">cf_returns_retained</a>. When using the 348 attribute, be sure to declare it within the proper macro that checks for 349 its availability, as it is not available in earlier versions of the analyzer:</p> 350 351 <pre class="code_example"> 352 <span class="command">$ cat test.m</span> 353 #ifndef __has_feature // Optional. 354 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 355 #endif 356 357 #ifndef CF_RETURNS_NOT_RETAINED 358 #if __has_feature(attribute_cf_returns_not_retained) 359 <span class="code_highlight">#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))</span> 360 #else 361 #define CF_RETURNS_NOT_RETAINED 362 #endif 363 #endif 364 </pre> 365 366 <h4 id="attr_ns_consumed">Attribute 'ns_consumed' 367 (Clang-specific)</h4> 368 369 <p>The 'ns_consumed' attribute can be placed on a specific parameter in either 370 the declaration of a function or an Objective-C method. It indicates to the 371 static analyzer that a <tt>release</tt> message is implicitly sent to the 372 parameter upon completion of the call to the given function or method. The 373 Foundation framework defines a macro <b><tt>NS_RELEASES_ARGUMENT</tt></b> that 374 is functionally equivalent to the <tt>NS_CONSUMED</tt> macro shown below.</p> 375 376 <p><b>Important note when using Garbage Collection</b>: Note that the analyzer 377 essentially ignores this attribute when code is compiled to use Objective-C 378 garbage collection. This is because the <tt>release</tt> message does nothing 379 when using GC. If the underlying function/method uses something like 380 <tt>CFRelease</tt> to decrement the reference count, consider using 381 the <a href="#attr_cf_consumed">cf_consumed</a> attribute instead.</p> 382 383 <p><b>Example</b></p> 384 385 <pre class="code_example"> 386 <span class="command">$ cat test.m</span> 387 #ifndef __has_feature // Optional. 388 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 389 #endif 390 391 #ifndef NS_CONSUMED 392 #if __has_feature(attribute_ns_consumed) 393 <span class="code_highlight">#define NS_CONSUMED __attribute__((ns_consumed))</span> 394 #else 395 #define NS_CONSUMED 396 #endif 397 #endif 398 399 void consume_ns(id <span class="code_highlight">NS_CONSUMED</span> x); 400 401 void test() { 402 id x = [[NSObject alloc] init]; 403 consume_ns(x); <b><i>// No leak!</i></b> 404 } 405 406 @interface Foo : NSObject 407 + (void) releaseArg:(id) <span class="code_highlight">NS_CONSUMED</span> x; 408 + (void) releaseSecondArg:(id)x second:(id) <span class="code_highlight">NS_CONSUMED</span> y; 409 @end 410 411 void test_method() { 412 id x = [[NSObject alloc] init]; 413 [Foo releaseArg:x]; <b><i>// No leak!</i></b> 414 } 415 416 void test_method2() { 417 id a = [[NSObject alloc] init]; 418 id b = [[NSObject alloc] init]; 419 [Foo releaseSecondArg:a second:b]; <b><i>// 'a' is leaked, but 'b' is released.</i></b> 420 } 421 </pre> 422 423 <h4 id="attr_cf_consumed">Attribute 'cf_consumed' 424 (Clang-specific)</h4> 425 426 <p>The 'cf_consumed' attribute is practically identical to <a 427 href="#attr_ns_consumed">ns_consumed</a>. The attribute can be placed on a 428 specific parameter in either the declaration of a function or an Objective-C 429 method. It indicates to the static analyzer that the object reference is 430 implicitly passed to a call to <tt>CFRelease</tt> upon completion of the call 431 to the given function or method. The CoreFoundation framework defines a macro 432 <b><tt>CF_RELEASES_ARGUMENT</tt></b> that is functionally equivalent to the 433 <tt>CF_CONSUMED</tt> macro shown below.</p> 434 435 <p>Operationally this attribute is nearly identical to 'ns_consumed' with the 436 main difference that the reference count decrement still occurs when using 437 Objective-C garbage collection (which is import for Core Foundation types, 438 which are not automatically garbage collected).</p> 439 440 <p><b>Example</b></p> 441 442 <pre class="code_example"> 443 <span class="command">$ cat test.m</span> 444 #ifndef __has_feature // Optional. 445 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 446 #endif 447 448 #ifndef CF_CONSUMED 449 #if __has_feature(attribute_cf_consumed) 450 <span class="code_highlight">#define CF_CONSUMED __attribute__((cf_consumed))</span> 451 #else 452 #define CF_CONSUMED 453 #endif 454 #endif 455 456 void consume_cf(id <span class="code_highlight">CF_CONSUMED</span> x); 457 void consume_CFDate(CFDateRef <span class="code_highlight">CF_CONSUMED</span> x); 458 459 void test() { 460 id x = [[NSObject alloc] init]; 461 consume_cf(x); <b><i>// No leak!</i></b> 462 } 463 464 void test2() { 465 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 466 consume_CFDate(date); <b><i>// No leak, including under GC!</i></b> 467 468 } 469 470 @interface Foo : NSObject 471 + (void) releaseArg:(CFDateRef) <span class="code_highlight">CF_CONSUMED</span> x; 472 @end 473 474 void test_method() { 475 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 476 [Foo releaseArg:date]; <b><i>// No leak!</i></b> 477 } 478 </pre> 479 480 <h4 id="attr_ns_consumes_self">Attribute 'ns_consumes_self' 481 (Clang-specific)</h4> 482 483 <p>The 'ns_consumes_self' attribute can be placed only on an Objective-C method 484 declaration. It indicates that the receiver of the message is 485 "consumed" (a single reference count decremented) after the message 486 is sent. This matches the semantics of all "init" methods.</p> 487 488 <p>One use of this attribute is declare your own init-like methods that do not 489 follow the standard Cocoa naming conventions.</p> 490 491 <p><b>Example</b></p> 492 493 <pre class="code_example"> 494 #ifndef __has_feature 495 #define __has_feature(x) 0 // Compatibility with non-clang compilers. 496 #endif 497 498 #ifndef NS_CONSUMES_SELF 499 #if __has_feature((attribute_ns_consumes_self)) 500 <span class="code_highlight">#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))</span> 501 #else 502 #define NS_CONSUMES_SELF 503 #endif 504 #endif 505 506 @interface MyClass : NSObject 507 - initWith:(MyClass *)x; 508 - nonstandardInitWith:(MyClass *)x <span class="code_highlight">NS_CONSUMES_SELF</span> NS_RETURNS_RETAINED; 509 @end 510 </pre> 511 512 <p>In this example, <tt>-nonstandardInitWith:</tt> has the same ownership 513 semantics as the init method <tt>-initWith:</tt>. The static analyzer will 514 observe that the method consumes the receiver, and then returns an object with 515 a +1 retain count.</p> 516 517 <p>The Foundation framework defines a macro <b><tt>NS_REPLACES_RECEIVER</tt></b> 518 which is functionally equivalent to the combination of <tt>NS_CONSUMES_SELF</tt> 519 and <tt>NS_RETURNS_RETAINED</tt> shown above.</p> 520 521 522 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 523 <h2 id="custom_assertions">Custom Assertion Handlers</h2> 524 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 525 526 <p>The analyzer exploits code assertions by pruning off paths where the 527 assertion condition is false. The idea is capture any program invariants 528 specified in the assertion that the developer may know but is not immediately 529 apparent in the code itself. In this way assertions make implicit assumptions 530 explicit in the code, which not only makes the analyzer more accurate when 531 finding bugs, but can help others better able to understand your code as well. 532 It can also help remove certain kinds of analyzer false positives by pruning off 533 false paths.</p> 534 535 <p>In order to exploit assertions, however, the analyzer must understand when it 536 encounters an "assertion handler." Typically assertions are 537 implemented with a macro, with the macro performing a check for the assertion 538 condition and, when the check fails, calling an assertion handler. For example, consider the following code 539 fragment:</p> 540 541 <pre class="code_example"> 542 void foo(int *p) { 543 assert(p != NULL); 544 } 545 </pre> 546 547 <p>When this code is preprocessed on Mac OS X it expands to the following:</p> 548 549 <pre class="code_example"> 550 void foo(int *p) { 551 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0); 552 } 553 </pre> 554 555 <p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called, 556 most assertion handlers typically print an error and terminate the program. The 557 analyzer can exploit such semantics by ending the analysis of a path once it 558 hits a call to an assertion handler.</p> 559 560 <p>The trick, however, is that the analyzer needs to know that a called function 561 is an assertion handler; otherwise the analyzer might assume the function call 562 returns and it will continue analyzing the path where the assertion condition 563 failed. This can lead to false positives, as the assertion condition usually 564 implies a safety condition (e.g., a pointer is not null) prior to performing 565 some action that depends on that condition (e.g., dereferencing a pointer).</p> 566 567 <p>The analyzer knows about several well-known assertion handlers, but can 568 automatically infer if a function should be treated as an assertion handler if 569 it is annotated with the 'noreturn' attribute or the (Clang-specific) 570 'analyzer_noreturn' attribute. Note that, currently, clang does not support 571 these attributes on Objective-C methods and C++ methods.</p> 572 573 <h4 id="attr_noreturn">Attribute 'noreturn'</h4> 574 575 <p>The 'noreturn' attribute is a GCC-attribute that can be placed on the 576 declarations of functions. It means exactly what its name implies: a function 577 with a 'noreturn' attribute should never return.</p> 578 579 <p>Specific details of the syntax of using the 'noreturn' attribute can be found 580 in <a 581 href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's 582 documentation</a>.</p> 583 584 <p>Not only does the analyzer exploit this information when pruning false paths, 585 but the compiler also takes it seriously and will generate different code (and 586 possibly better optimized) under the assumption that the function does not 587 return.</p> 588 589 <p><b>Example</b></p> 590 591 <p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in 592 <tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p> 593 594 <pre class="code_example"> 595 void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>; 596 </pre> 597 598 <h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4> 599 600 <p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to 601 'noreturn' except that it is ignored by the compiler for the purposes of code 602 generation.</p> 603 604 <p>This attribute is useful for annotating assertion handlers that actually 605 <em>can</em> return, but for the purpose of using the analyzer we want to 606 pretend that such functions do not return.</p> 607 608 <p>Because this attribute is Clang-specific, its use should be conditioned with 609 the use of preprocessor macros.</p> 610 611 <p><b>Example</b> 612 613 <pre class="code_example"> 614 #ifndef CLANG_ANALYZER_NORETURN 615 #if __has_feature(attribute_analyzer_noreturn) 616 <span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span> 617 #else 618 #define CLANG_ANALYZER_NORETURN 619 #endif 620 #endif 621 622 void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>; 623 </pre> 624 625 </div> 626 </div> 627 </body> 628 </html> 629 630