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 | |