| 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 | <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 |
| 92 | function expects that a given function parameter is not a null pointer. Specific |
| 93 | details of the syntax of using the 'nonnull' attribute can be found in <a |
| 94 | href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-2263">GCC's |
| 95 | documentation</a>.</p> |
| 96 | |
| 97 | <p>Both the Clang compiler and GCC will flag warnings for simple cases where a |
| 98 | null 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 |
| 100 | symbolic analysis to track what pointer values are potentially null and then |
| 101 | flag warnings when they are passed in a function call via a 'nonnull' |
| 102 | parameter.</p> |
| 103 | |
| 104 | <p><b>Example</b></p> |
| 105 | |
| 106 | <pre class="code_example"> |
| 107 | <span class="command">$ cat test.m</span> |
| 108 | int bar(int*p, int q, int *r) __attribute__((nonnull(1,3))); |
| 109 | |
| 110 | int 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 |
| 117 | output:</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 |
| 126 | Annotations</h3> |
| 127 | |
| 128 | <!-- |
| 129 | <p>As described in <a href="/available_checks.html#retain_release">Available |
| 130 | Checks</a>, |
| 131 | --> |
| 132 | <p>The analyzer supports the proper management of retain counts for |
| 133 | both Cocoa and Core Foundation objects. This checking is largely based on |
| 134 | enforcing Cocoa and Core Foundation naming conventions for Objective-C methods |
| 135 | (Cocoa) and C functions (Core Foundation). Not strictly following these |
| 136 | conventions 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 |
| 139 | functions that deviate from the Cocoa and Core Foundation conventions using the |
| 140 | attributes described here. However, you should consider using proper naming |
| 141 | conventions or the <a |
| 142 | href="http://clang.llvm.org/docs/LanguageExtensions.html#the-objc-method-family-attribute"><tt>objc_method_family</tt></a> |
| 143 | attribute, 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 |
| 149 | annotate an Objective-C method or C function as returning a retained Cocoa |
| 150 | object that the caller is responsible for releasing (via sending a |
| 151 | <tt>release</tt> message to the object). The Foundation framework defines a |
| 152 | macro <b><tt>NS_RETURNS_RETAINED</tt></b> that is functionally equivalent to the |
| 153 | one shown below.</p> |
| 154 | |
| 155 | <p><b>Placing on Objective-C methods</b>: For Objective-C methods, this |
| 156 | annotation essentially tells the analyzer to treat the method as if its name |
| 157 | begins 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 |
| 161 | analyzer typically does not make any assumptions about whether or not the object |
| 162 | is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C |
| 163 | functions 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 |
| 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. |
| 247 | |
| 248 | This distinction is important for the following reason: |
| 249 | as Core Foundation is a C API, |
| 250 | the analyzer cannot always tell that a pointer return value refers to a |
| 251 | Core Foundation object. |
| 252 | 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 | |
| 256 | <p><b>Placing on C functions</b>: When placing the attribute |
| 257 | 'cf_returns_retained' on the declarations of C functions, the analyzer |
| 258 | interprets 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 |
| 263 | contained the keywords "create" or "copy". This means the |
| 264 | returned object as a +1 retain count that must be released by the caller, either |
| 265 | by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C |
| 266 | object 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> |
| 295 | CFDateRef 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 |
| 322 | href="#attr_cf_returns_retained">cf_returns_retained</a>'. Where a function or |
| 323 | method may appear to obey the Core Foundation or Cocoa conventions and return |
| 324 | a retained Core Foundation object, this attribute can be used to indicate that |
| 325 | the object reference returned should not be considered as an |
| 326 | "owning" reference being returned to the caller. The |
| 327 | CoreFoundation framework defines a macro <b><tt>CF_RETURNS_NOT_RETAINED</tt></b> |
| 328 | that is functionally equivalent to the one shown below.</p> |
| 329 | |
| 330 | <p>Usage is identical to <a |
| 331 | href="#attr_cf_returns_retained">cf_returns_retained</a>. When using the |
| 332 | attribute, be sure to declare it within the proper macro that checks for |
| 333 | its 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 |
| 354 | the declaration of a function or an Objective-C method. It indicates to the |
| 355 | static analyzer that a <tt>release</tt> message is implicitly sent to the |
| 356 | parameter upon completion of the call to the given function or method. The |
| 357 | Foundation framework defines a macro <b><tt>NS_RELEASES_ARGUMENT</tt></b> that |
| 358 | is 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 | |
| 376 | void consume_ns(id <span class="code_highlight">NS_CONSUMED</span> x); |
| 377 | |
| 378 | void 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 | |
| 388 | void test_method() { |
| 389 | id x = [[NSObject alloc] init]; |
| 390 | [Foo releaseArg:x]; <b><i>// No leak!</i></b> |
| 391 | } |
| 392 | |
| 393 | void 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 |
| 404 | href="#attr_ns_consumed">ns_consumed</a>. The attribute can be placed on a |
| 405 | specific parameter in either the declaration of a function or an Objective-C |
| 406 | method. It indicates to the static analyzer that the object reference is |
| 407 | implicitly passed to a call to <tt>CFRelease</tt> upon completion of the call |
| 408 | to 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 | |
| 430 | void consume_cf(id <span class="code_highlight">CF_CONSUMED</span> x); |
| 431 | void consume_CFDate(CFDateRef <span class="code_highlight">CF_CONSUMED</span> x); |
| 432 | |
| 433 | void test() { |
| 434 | id x = [[NSObject alloc] init]; |
| 435 | consume_cf(x); <b><i>// No leak!</i></b> |
| 436 | } |
| 437 | |
| 438 | void 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 | |
| 448 | void 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 |
| 458 | declaration. It indicates that the receiver of the message is |
| 459 | "consumed" (a single reference count decremented) after the message |
| 460 | is 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 |
| 463 | follow 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 |
| 487 | semantics as the init method <tt>-initWith:</tt>. The static analyzer will |
| 488 | observe that the method consumes the receiver, and then returns an object with |
| 489 | a +1 retain count.</p> |
| 490 | |
| 491 | <p>The Foundation framework defines a macro <b><tt>NS_REPLACES_RECEIVER</tt></b> |
| 492 | which is functionally equivalent to the combination of <tt>NS_CONSUMES_SELF</tt> |
| 493 | and <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> |
| 499 | requires developers to inherit all heap allocated objects from <tt>OSObject</tt> |
| 500 | and to perform manual reference counting. |
| 501 | The 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> |
| 503 | or to CoreFoundation reference counting. |
| 504 | Freshly-allocated objects start with a reference count of 1, |
| 505 | and calls to <tt>retain</tt> increment it, |
| 506 | while calls to <tt>release</tt> decrement it. |
| 507 | The object is deallocated whenever its reference count reaches zero.</p> |
| 508 | |
| 509 | <p>Manually incrementing and decrementing reference counts is error-prone: |
| 510 | over-retains lead to leaks, and over-releases lead to uses-after-free. |
| 511 | The analyzer can help the programmer to check for unbalanced |
| 512 | retain/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, |
| 517 | and the declarations (not the definitions) of all the functions it interacts |
| 518 | with.</p> |
| 519 | |
| 520 | <p>In order to support such reasoning, it should be possible to <em>summarize</em> |
| 521 | the behavior of each function, with respect to reference count |
| 522 | of 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> |
| 551 | LIBKERN_RETURNS_RETAINED</tt>) plays a role identical to <a |
| 552 | href="#attr_ns_returns_retained">ns_returns_retained</a> for functions |
| 553 | returning <tt>OSObject</tt> subclasses. |
| 554 | The attribute indicates that it is a callers responsibility to release the |
| 555 | returned 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> |
| 562 | LIBKERN_RETURNS_NOT_RETAINED</tt>) plays a role identical to <a |
| 563 | href="#attr_ns_returns_not_retained">ns_returns_not_retained</a> for functions |
| 564 | returning <tt>OSObject</tt> subclasses. |
| 565 | The attribute indicates that the caller should not change the retain |
| 566 | count of the returned object. |
| 567 | </p> |
| 568 | |
| 569 | <h5>Example</h5> |
| 570 | |
| 571 | <pre class="code_example"> |
| 572 | class 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. |
| 579 | OSObject * 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, |
| 588 | applied to a parameter, |
| 589 | indicates that the call to the function <em>consumes</em> the parameter: |
| 590 | the callee should either release it or store it and release it in the destructor, |
| 591 | while the caller should assume one is subtracted from the reference count |
| 592 | after the call.</p> |
| 593 | |
| 594 | <pre class="code_example"> |
| 595 | IOReturn 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>, |
| 601 | the <tt>os_consumes_self</tt> attribute indicates that the method call |
| 602 | <em>consumes</em> the implicit <tt>this</tt> argument: the caller |
| 603 | should assume one was subtracted from the reference count of the object |
| 604 | after the call, and the callee has on obligation to either |
| 605 | release the argument, or store it and eventually release it in the |
| 606 | destructor.</p> |
| 607 | |
| 608 | <pre class="code_example"> |
| 609 | void addThisToList(OSArray *givenList) LIBKERN_CONSUMES_THIS; |
| 610 | </pre> |
| 611 | |
| 612 | <h4 id="os_out_parameters">Out Parameters</h4> |
| 613 | |
| 614 | A 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 |
| 616 | object into an argument). |
| 617 | Currently the analyzer does not track unannotated out |
| 618 | parameters 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"> |
| 624 | void 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 |
| 628 | caller has no further obligations.</p> |
| 629 | |
| 630 | <p><b>2. Retained out parameters</b>, |
| 631 | identified using <tt>LIBKERN_RETURNS_RETAINED</tt>:</p> |
| 632 | <pre class="code_example"> |
| 633 | void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj) |
| 634 | </pre> |
| 635 | <p> |
| 636 | In 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"> |
| 642 | bool 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 |
| 648 | success:</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). |
| 652 | For 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> |
| 655 | The annotation <tt>LIBKERN_RETURNS_RETAINED_ON_ZERO</tt> states |
| 656 | that a retained object is written into if and only if the function returns a zero value:</p> |
| 657 | |
| 658 | <pre class="code_example"> |
| 659 | bool 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> |
| 665 | Similarly, <tt>LIBKERN_RETURNS_RETAINED_ON_NONZERO</tt> specifies that a |
| 666 | retained object is written into the parameter if and only if the function has |
| 667 | returned a non-zero value.</p> |
| 668 | |
| 669 | <p>Note that for non-retained out parameters conditionals do not matter, as the |
| 670 | caller has no obligations regardless of whether an object is written into or |
| 671 | not.</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 |
| 678 | assertion condition is false. The idea is capture any program invariants |
| 679 | specified in the assertion that the developer may know but is not immediately |
| 680 | apparent in the code itself. In this way assertions make implicit assumptions |
| 681 | explicit in the code, which not only makes the analyzer more accurate when |
| 682 | finding bugs, but can help others better able to understand your code as well. |
| 683 | It can also help remove certain kinds of analyzer false positives by pruning off |
| 684 | false paths.</p> |
| 685 | |
| 686 | <p>In order to exploit assertions, however, the analyzer must understand when it |
| 687 | encounters an "assertion handler." Typically assertions are |
| 688 | implemented with a macro, with the macro performing a check for the assertion |
| 689 | condition and, when the check fails, calling an assertion handler. For example, consider the following code |
| 690 | fragment:</p> |
| 691 | |
| 692 | <pre class="code_example"> |
| 693 | void 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"> |
| 701 | void 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, |
| 707 | most assertion handlers typically print an error and terminate the program. The |
| 708 | analyzer can exploit such semantics by ending the analysis of a path once it |
| 709 | hits a call to an assertion handler.</p> |
| 710 | |
| 711 | <p>The trick, however, is that the analyzer needs to know that a called function |
| 712 | is an assertion handler; otherwise the analyzer might assume the function call |
| 713 | returns and it will continue analyzing the path where the assertion condition |
| 714 | failed. This can lead to false positives, as the assertion condition usually |
| 715 | implies a safety condition (e.g., a pointer is not null) prior to performing |
| 716 | some 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 |
| 719 | automatically infer if a function should be treated as an assertion handler if |
| 720 | it is annotated with the 'noreturn' attribute or the (Clang-specific) |
| 721 | 'analyzer_noreturn' attribute. Note that, currently, clang does not support |
| 722 | these 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 |
| 727 | declarations of functions. It means exactly what its name implies: a function |
| 728 | with a 'noreturn' attribute should never return.</p> |
| 729 | |
| 730 | <p>Specific details of the syntax of using the 'noreturn' attribute can be found |
| 731 | in <a |
| 732 | href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's |
| 733 | documentation</a>.</p> |
| 734 | |
| 735 | <p>Not only does the analyzer exploit this information when pruning false paths, |
| 736 | but the compiler also takes it seriously and will generate different code (and |
| 737 | possibly better optimized) under the assumption that the function does not |
| 738 | return.</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"> |
| 746 | void __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 |
| 753 | generation.</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 |
| 757 | pretend that such functions do not return.</p> |
| 758 | |
| 759 | <p>Because this attribute is Clang-specific, its use should be conditioned with |
| 760 | the 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 | |
| 773 | void 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 | |