blob: b33b4bfcdde93223c1a9c57bff8f624ab42d5f2c [file] [log] [blame]
Ted Kremenek591b9072009-06-08 21:21:24 +00001<!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" />
Ted Kremenekf4aed5f2010-02-12 21:05:44 +00008 <script type="text/javascript" src="scripts/menu.js"></script>
Ted Kremenek591b9072009-06-08 21:21:24 +00009</head>
10<body>
11
Ted Kremenek8bebc6e2010-02-09 23:05:59 +000012<div id="page">
Ted Kremenek591b9072009-06-08 21:21:24 +000013<!--#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
21attributes</a> and pragmas that can help make using the Clang Static Analyzer
22more useful. These annotations can both help suppress false positives as well as
23enhance the analyzer's ability to find bugs.</p>
24
25<p>This page gives a practical overview of such annotations. For more technical
26specifics regarding Clang-specific annotations please see the Clang's list of <a
27href="http://clang.llvm.org/docs/LanguageExtensions.html">language
28extensions</a>. Details of &quot;standard&quot; GCC attributes (that Clang also
29supports) can be found in the <a href="http://gcc.gnu.org/onlinedocs/gcc/">GCC
30manual</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
32attributes</a>.</p>
33
34<p>Note that attributes that are labeled <b>Clang-specific</b> are not
35recognized by GCC. Their use can be conditioned using preprocessor macros
36(examples included on this page).</p>
37
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000038<h4>Specific Topics</h4>
39
Ted Kremenek11fe1752011-01-27 18:43:03 +000040<ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000041<li><a href="#generic">Annotations to Enhance Generic Checks</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000042 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000043 <li><a href="#null_checking"><span>Null Pointer Checking</span></a>
Ted Kremenek591b9072009-06-08 21:21:24 +000044 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000045 <li><a href="#attr_nonnull"><span>Attribute 'nonnull'</span></a></li>
Ted Kremenek591b9072009-06-08 21:21:24 +000046 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000047 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000048 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000049</li>
50<li><a href="#macosx">Mac OS X API Annotations</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000051 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000052 <li><a href="#cocoa_mem">Cocoa &amp; Core Foundation Memory Management Annotations</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000053 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000054 <li><a href="#attr_ns_returns_retained">Attribute 'ns_returns_retained'</a></li>
Ted Kremeneka238f872010-05-14 18:13:43 +000055 <li><a href="#attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'</a></li>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000056 <li><a href="#attr_cf_returns_retained">Attribute 'cf_returns_retained'</a></li>
Ted Kremeneka238f872010-05-14 18:13:43 +000057 <li><a href="#attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'</a></li>
Ted Kremenek11fe1752011-01-27 18:43:03 +000058 <li><a href="#attr_ns_consumed">Attribute 'ns_consumed'</a></li>
59 <li><a href="#attr_cf_consumed">Attribute 'cf_consumed'</a></li>
Ted Kremenek12b94342011-01-27 06:54:14 +000060 <li><a href="#attr_ns_consumes_self">Attribute 'ns_consumes_self'</a></li>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000061 </ul>
62 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000063 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000064</li>
65<li><a href="#custom_assertions">Custom Assertion Handlers</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000066 <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>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000070 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000071</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
82function expects that a given function parameter is not a null pointer. Specific
83details of the syntax of using the 'nonnull' attribute can be found in <a
84href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-2263">GCC's
85documentation</a>.</p>
86
87<p>Both the Clang compiler and GCC will flag warnings for simple cases where a
88null 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
90symbolic analysis to track what pointer values are potentially null and then
91flag warnings when they are passed in a function call via a 'nonnull'
92parameter.</p>
93
94<p><b>Example</b></p>
95
96<pre class="code_example">
97<span class="command">$ cat test.m</span>
98int bar(int*p, int q, int *r) __attribute__((nonnull(1,3)));
99
100int foo(int *p, int *q) {
101 return !p ? bar(q, 2, p)
102 : bar(p, 2, q);
103}
Ted Kremenek591b9072009-06-08 21:21:24 +0000104</pre>
105
Ted Kremenek42291dd2009-06-24 19:17:54 +0000106<p>Running <tt>scan-build</tt> over this source produces the following
107output:</p>
108
Ted Kremenek5ceab862009-06-24 19:20:24 +0000109<img src="images/example_attribute_nonnull.png">
Ted Kremenek42291dd2009-06-24 19:17:54 +0000110
Ted Kremenek591b9072009-06-08 21:21:24 +0000111<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
112<h2 id="macosx">Mac OS X API Annotations</h2>
113<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
114
115<h3 id="cocoa_mem">Cocoa &amp; Core Foundation Memory Management
116Annotations</h3>
117
Ted Kremenekcb41f3e2009-06-09 01:32:41 +0000118<!--
Ted Kremenek591b9072009-06-08 21:21:24 +0000119<p>As described in <a href="/available_checks.html#retain_release">Available
Ted Kremenekcb41f3e2009-06-09 01:32:41 +0000120Checks</a>,
121-->
122<p>The analyzer supports the proper management of retain counts for
Ted Kremenek591b9072009-06-08 21:21:24 +0000123both Cocoa and Core Foundation objects. This checking is largely based on
124enforcing Cocoa and Core Foundation naming conventions for Objective-C methods
125(Cocoa) and C functions (Core Foundation). Not strictly following these
126conventions 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
129functions that deviate from the Cocoa and Core Foundation conventions using the
130attributes described here.</p>
131
132<h4 id="attr_ns_returns_retained">Attribute 'ns_returns_retained'
133(Clang-specific)</h4>
134
135<p>The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to
136annotate an Objective-C method or C function as returning a retained Cocoa
137object that the caller is responsible for releasing (via sending a
138<tt>release</tt> message to the object).</p>
139
140<p><b>Placing on Objective-C methods</b>: For Objective-C methods, this
141annotation essentially tells the analyzer to treat the method as if its name
142begins with &quot;alloc&quot; or &quot;new&quot; or contais the word
143&quot;copy&quot;.</p>
144
145<p><b>Placing on C functions</b>: For C functions returning Cocoa objects, the
146analyzer typically does not make any assumptions about whether or not the object
147is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C
148functions allows the analyzer to perform extra checking.</p>
149
150<p><b>Important note when using Garbage Collection</b>: Note that the analyzer
151interprets this attribute slightly differently when using Objective-C garbage
152collection (available on Mac OS 10.5+). When analyzing Cocoa code that uses
153garbage collection, &quot;alloc&quot; methods are assumed to return an object
154that is managed by the garbage collector (and thus doesn't have a retain count
155the caller must balance). These same assumptions are applied to methods or
156functions annotated with 'ns_returns_retained'. If you are returning a Core
157Foundation object (which may not be managed by the garbage collector) you should
158use 'cf_returns_retained'.</p>
159
160<p><b>Example</b></p>
161
162<pre class="code_example">
163<span class="command">$ cat test.m</span>
164#import &lt;Foundation/Foundation.h&gt;
165
Ted Kremenek21375a32009-07-17 00:25:49 +0000166#ifndef __has_feature // Optional.
167#define __has_feature(x) 0 // Compatibility with non-clang compilers.
168#endif
169
Ted Kremenek591b9072009-06-08 21:21:24 +0000170#ifndef NS_RETURNS_RETAINED
Ted Kremenek21375a32009-07-17 00:25:49 +0000171#if __has_feature(attribute_ns_returns_retained)
Ted Kremenek591b9072009-06-08 21:21:24 +0000172<span class="code_highlight">#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))</span>
173#else
174#define NS_RETURNS_RETAINED
175#endif
176#endif
177
178@interface MyClass : NSObject {}
179- (NSString*) returnsRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
180- (NSString*) alsoReturnsRetained;
181@end
182
183@implementation MyClass
184- (NSString*) returnsRetained {
185 return [[NSString alloc] initWithCString:"no leak here"];
186}
187- (NSString*) alsoReturnsRetained {
188 return [[NSString alloc] initWithCString:"flag a leak"];
189}
190@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000191</pre>
192
Ted Kremenek7d277e22009-06-24 18:50:14 +0000193<p>Running <tt>scan-build</tt> on this source file produces the following output:</p>
194
195<img src="images/example_ns_returns_retained.png">
196
Ted Kremeneka238f872010-05-14 18:13:43 +0000197<h4 id="attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'
198(Clang-specific)</h4>
199
200<p>The 'ns_returns_not_retained' attribute is the complement of '<a
201href="#attr_ns_returns_retained">ns_returns_retained</a>'. Where a function or
202method may appear to obey the Cocoa conventions and return a retained Cocoa
203object, this attribute can be used to indicate that the object reference
204returned should not be considered as an &quot;owning&quot; reference being
205returned to the caller.</p>
206
207<p>Usage is identical to <a
208href="#attr_ns_returns_retained">ns_returns_retained</a>. When using the
209attribute, be sure to declare it within the proper macro that checks for
210its availability, as it is not available in earlier versions of the analyzer:</p>
211
212<pre class="code_example">
213<span class="command">$ cat test.m</span>
214#ifndef __has_feature // Optional.
215#define __has_feature(x) 0 // Compatibility with non-clang compilers.
216#endif
217
218#ifndef NS_RETURNS_NOT_RETAINED
219#if __has_feature(attribute_ns_returns_not_retained)
220<span class="code_highlight">#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))</span>
221#else
222#define NS_RETURNS_NOT_RETAINED
223#endif
224#endif
225</pre>
226
Ted Kremenek591b9072009-06-08 21:21:24 +0000227<h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
228(Clang-specific)</h4>
229
230<p>The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to
231annotate an Objective-C method or C function as returning a retained Core
232Foundation object that the caller is responsible for releasing.
233
234<p><b>Placing on Objective-C methods</b>: With respect to Objective-C methods.,
235this attribute is identical in its behavior and usage to 'ns_returns_retained'
236except for the distinction of returning a Core Foundation object instead of a
237Cocoa object. This distinction is important for two reasons:</p>
238
239<ul>
240 <li>Core Foundation objects are not automatically managed by the Objective-C
241 garbage collector.</li>
242 <li>Because Core Foundation is a C API, the analyzer cannot always tell that a
243 pointer return value refers to a Core Foundation object. In contrast, it is
244 trivial for the analyzer to recognize if a pointer refers to a Cocoa object
245 (given the Objective-C type system).</p>
246</ul>
247
248<p><b>Placing on C functions</b>: When placing the attribute
249'cf_returns_retained' on the declarations of C functions, the analyzer
250interprets the function as:</p>
251
252<ol>
253 <li>Returning a Core Foundation Object</li>
254 <li>Treating the function as if it its name
255contained the keywords &quot;create&quot; or &quot;copy&quot;. This means the
256returned object as a +1 retain count that must be released by the caller, either
257by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C
258object pointer), calling <tt>CFRelease</tt> (or similar function), or using
259<tt>CFMakeCollectable</tt> to register the object with the Objective-C garbage
260collector.</li>
261</ol>
262
263<p><b>Example</b></p>
264
265<p>In this example, observe the difference in output when the code is compiled
266to not use garbage collection versus when it is compiled to only use garbage
267collection (<tt>-fobjc-gc-only</tt>).</p>
268
269<pre class="code_example">
270<span class="command">$ cat test.m</span>
271$ cat test.m
272#import &lt;Cocoa/Cocoa.h&gt;
273
Ted Kremenek21375a32009-07-17 00:25:49 +0000274#ifndef __has_feature // Optional.
275#define __has_feature(x) 0 // Compatibility with non-clang compilers.
276#endif
277
Ted Kremenek591b9072009-06-08 21:21:24 +0000278#ifndef CF_RETURNS_RETAINED
Ted Kremenek21375a32009-07-17 00:25:49 +0000279#if __has_feature(attribute_cf_returns_retained)
Ted Kremenek591b9072009-06-08 21:21:24 +0000280<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
281#else
282#define CF_RETURNS_RETAINED
283#endif
284#endif
285
286@interface MyClass : NSObject {}
287- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
288- (NSDate*) alsoReturnsRetained;
289- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
290@end
291
292<span class="code_highlight">CF_RETURNS_RETAINED</span>
293CFDateRef returnsRetainedCFDate() {
294 return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
295}
296
297@implementation MyClass
298- (NSDate*) returnsCFRetained {
Ted Kremenek11fe1752011-01-27 18:43:03 +0000299 return (NSDate*) returnsRetainedCFDate(); <b><i>// No leak.</i></b>
Ted Kremenek591b9072009-06-08 21:21:24 +0000300}
301
302- (NSDate*) alsoReturnsRetained {
Ted Kremenek11fe1752011-01-27 18:43:03 +0000303 return (NSDate*) returnsRetainedCFDate(); <b><i>// Always report a leak.</i></b>
Ted Kremenek591b9072009-06-08 21:21:24 +0000304}
305
306- (NSDate*) returnsNSRetained {
Ted Kremenek11fe1752011-01-27 18:43:03 +0000307 return (NSDate*) returnsRetainedCFDate(); <b><i>// Report a leak when using GC.</i></b>
Ted Kremenek591b9072009-06-08 21:21:24 +0000308}
309@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000310</pre>
311
Ted Kremenek6fe1ef22009-06-24 19:04:37 +0000312<p>Running <tt>scan-build</tt> on this example produces the following output:</p>
313
314<img src="images/example_cf_returns_retained.png">
315
316</p>When the above code is compiled using Objective-C garbage collection (i.e.,
317code is compiled with the flag <tt>-fobjc-gc</tt> or <tt>-fobjc-gc-only</tt>),
318<tt>scan-build</tt> produces both the above error (with slightly different text
319to indicate the code uses garbage collection) as well as the following warning,
320which indicates a leak that occurs <em>only</em> when using garbage
321collection:</p>
322
323<img src="images/example_cf_returns_retained_gc.png">
324
Ted Kremeneka238f872010-05-14 18:13:43 +0000325<h4 id="attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'
326(Clang-specific)</h4>
327
328<p>The 'cf_returns_not_retained' attribute is the complement of '<a
329href="#attr_cf_returns_retained">cf_returns_retained</a>'. Where a function or
330method may appear to obey the Core Foundation or Cocoa conventions and return
331a retained Core Foundation object, this attribute can be used to indicate that
332the object reference returned should not be considered as an
333&quot;owning&quot; reference being returned to the caller.</p>
334
335<p>Usage is identical to <a
336href="#attr_cf_returns_retained">cf_returns_retained</a>. When using the
337attribute, be sure to declare it within the proper macro that checks for
338its availability, as it is not available in earlier versions of the analyzer:</p>
339
340<pre class="code_example">
341<span class="command">$ cat test.m</span>
342#ifndef __has_feature // Optional.
343#define __has_feature(x) 0 // Compatibility with non-clang compilers.
344#endif
345
346#ifndef CF_RETURNS_NOT_RETAINED
347#if __has_feature(attribute_cf_returns_not_retained)
348<span class="code_highlight">#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))</span>
349#else
350#define CF_RETURNS_NOT_RETAINED
351#endif
352#endif
353</pre>
354
Ted Kremenek11fe1752011-01-27 18:43:03 +0000355<h4 id="attr_ns_consumed">Attribute 'ns_consumed'
356(Clang-specific)</h4>
357
358<p>The 'ns_consumed' attribute can be placed on a specific parameter in either the declaration of a function or an Objective-C method.
359 It indicates to the static analyzer that a <tt>release</tt> message is implicitly sent to the parameter upon
360 completion of the call to the given function or method.
361
362<p><b>Important note when using Garbage Collection</b>: Note that the analyzer
363essentially ignores this attribute when code is compiled to use Objective-C
364garbage collection. This is because the <tt>release</tt> message does nothing
365when using GC. If the underlying function/method uses something like
366<tt>CFRelease</tt> to decrement the reference count, consider using
367the <a href="#attr_cf_consumed">cf_consumed</a> attribute instead.</p>
368
369<p><b>Example</b></p>
370
371<pre class="code_example">
372<span class="command">$ cat test.m</span>
373#ifndef __has_feature // Optional.
374#define __has_feature(x) 0 // Compatibility with non-clang compilers.
375#endif
376
377#ifndef NS_CONSUMED
378#if __has_feature(attribute_ns_consumed)
Ted Kremenek1e4162f2011-01-27 22:00:02 +0000379<span class="code_highlight">#define NS_CONSUMED __attribute__((ns_consumed))</span>
Ted Kremenek11fe1752011-01-27 18:43:03 +0000380#else
381#define NS_CONSUMED
382#endif
383#endif
384
385void consume_ns(id <span class="code_highlight">NS_CONSUMED</span> x);
386
387void test() {
388 id x = [[NSObject alloc] init];
389 consume_ns(x); <b><i>// No leak!</i></b>
390}
391
392@interface Foo : NSObject
393+ (void) releaseArg:(id) <span class="code_highlight">NS_CONSUMED</span> x;
394+ (void) releaseSecondArg:(id)x second:(id) <span class="code_highlight">NS_CONSUMED</span> y;
395@end
396
397void test_method() {
398 id x = [[NSObject alloc] init];
399 [Foo releaseArg:x]; <b><i>// No leak!</i></b>
400}
401
402void test_method2() {
403 id a = [[NSObject alloc] init];
404 id b = [[NSObject alloc] init];
405 [Foo releaseSecondArg:a second:b]; <b><i>// 'a' is leaked, but 'b' is released.</i></b>
406}
407</pre>
408
409<h4 id="attr_cf_consumed">Attribute 'cf_consumed'
410(Clang-specific)</h4>
411
412<p>The 'cf_consumed' attribute is practically identical to <a href="#attr_ns_consumed">ns_consumed</a>.
413The attribute can be placed on a specific parameter in either the declaration of a function or an Objective-C method.
414It indicates to the static analyzer that the object reference is implicitly passed to a call to <tt>CFRelease</tt> upon
415completion of the call to the given function or method.</p>
416
417<p>Operationally this attribute is nearly identical to ns_consumed
418with the main difference that the reference count decrement still occurs when using Objective-C garbage
419collection (which is import for Core Foundation types, which are not automatically garbage collected).</p>
420
421<p><b>Example</b></p>
422
423<pre class="code_example">
424<span class="command">$ cat test.m</span>
425#ifndef __has_feature // Optional.
426#define __has_feature(x) 0 // Compatibility with non-clang compilers.
427#endif
428
429#ifndef CF_CONSUMED
430#if __has_feature(attribute_cf_consumed)
Ted Kremenek1e4162f2011-01-27 22:00:02 +0000431<span class="code_highlight">#define CF_CONSUMED __attribute__((cf_consumed))</span>
Ted Kremenek11fe1752011-01-27 18:43:03 +0000432#else
433#define CF_CONSUMED
434#endif
435#endif
436
437void consume_cf(id <span class="code_highlight">CF_CONSUMED</span> x);
438void consume_CFDate(CFDateRef <span class="code_highlight">CF_CONSUMED</span> x);
439
440void test() {
441 id x = [[NSObject alloc] init];
442 consume_cf(x); <b><i>// No leak!</i></b>
443}
444
445void test2() {
446 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
447 consume_CFDate(date); <b><i>// No leak, including under GC!</i></b>
448
449}
450
451@interface Foo : NSObject
452+ (void) releaseArg:(CFDateRef) <span class="code_highlight">CF_CONSUMED</span> x;
453@end
454
455void test_method() {
456 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
457 [Foo releaseArg:date]; <b><i>// No leak!</i></b>
458}
459</pre>
460
Ted Kremenek12b94342011-01-27 06:54:14 +0000461<h4 id="attr_ns_consumes_self">Attribute 'ns_consumes_self'
462(Clang-specific)</h4>
463
464<p>The 'ns_consumes_self' attribute can be placed only on an Objective-C method declaration.
465 It indicates that the receiver of the message is &quot;consumed&quot; (a single reference count decremented)
466 after the message is sent. This matches the semantics of all &quot;init&quot; methods.
467</p>
468
469<p>One use of this attribute is declare your own init-like methods that do not follow the
Ted Kremenek11fe1752011-01-27 18:43:03 +0000470 standard Cocoa naming conventions.</p>
471
472<p><b>Example</b></p>
Ted Kremenek12b94342011-01-27 06:54:14 +0000473
474<pre class="code_example">
475#ifndef __has_feature
Ted Kremeneka018c272011-01-27 06:59:29 +0000476#define __has_feature(x) 0 // Compatibility with non-clang compilers.
Ted Kremenek12b94342011-01-27 06:54:14 +0000477#endif
478
479#ifndef NS_CONSUMES_SELF
Ted Kremeneke2abf092011-01-27 07:02:03 +0000480#if __has_feature((attribute_ns_consumes_self))
481<span class="code_highlight">#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))</span>
Ted Kremenek12b94342011-01-27 06:54:14 +0000482#else
483#define NS_CONSUMES_SELF
484#endif
485#endif
486
487@interface MyClass : NSObject
488- initWith:(MyClass *)x;
Ted Kremeneka018c272011-01-27 06:59:29 +0000489- nonstandardInitWith:(MyClass *)x <span class="code_highlight">NS_CONSUMES_SELF</span> NS_RETURNS_RETAINED;
Ted Kremenek12b94342011-01-27 06:54:14 +0000490@end
491</pre>
492
493<p>In this example, <tt>nonstandardInitWith:</tt> has the same ownership semantics as the init method <tt>initWith:</tt>.
494 The static analyzer will observe that the method consumes the receiver, and then returns an object with a +1 retain count.</p>
495
Ted Kremenek591b9072009-06-08 21:21:24 +0000496<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
497<h2 id="custom_assertions">Custom Assertion Handlers</h2>
498<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
499
500<p>The analyzer exploits code assertions by pruning off paths where the
501assertion condition is false. The idea is capture any program invariants
502specified in the assertion that the developer may know but is not immediately
503apparent in the code itself. In this way assertions make implicit assumptions
504explicit in the code, which not only makes the analyzer more accurate when
505finding bugs, but can help others better able to understand your code as well.
506It can also help remove certain kinds of analyzer false positives by pruning off
507false paths.</p>
508
509<p>In order to exploit assertions, however, the analyzer must understand when it
510encounters an &quot;assertion handler.&quot; Typically assertions are
511implemented with a macro, with the macro performing a check for the assertion
512condition and, when the check fails, calling an assertion handler. For example, consider the following code
513fragment:</p>
514
515<pre class="code_example">
516void foo(int *p) {
517 assert(p != NULL);
518}
519</pre>
520
521<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
522
523<pre class="code_example">
524void foo(int *p) {
525 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
526}
527</pre>
528
529<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
530most assertion handlers typically print an error and terminate the program. The
531analyzer can exploit such semantics by ending the analysis of a path once it
532hits a call to an assertion handler.</p>
533
534<p>The trick, however, is that the analyzer needs to know that a called function
535is an assertion handler; otherwise the analyzer might assume the function call
536returns and it will continue analyzing the path where the assertion condition
537failed. This can lead to false positives, as the assertion condition usually
538implies a safety condition (e.g., a pointer is not null) prior to performing
539some action that depends on that condition (e.g., dereferencing a pointer).</p>
540
541<p>The analyzer knows about several well-known assertion handlers, but can
542automatically infer if a function should be treated as an assertion handler if
543it is annotated with the 'noreturn' attribute or the (Clang-specific)
544'analyzer_noreturn' attribute.</p>
545
546<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
547
548<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
549declarations of functions. It means exactly what its name implies: a function
550with a 'noreturn' attribute should never return.</p>
551
552<p>Specific details of the syntax of using the 'noreturn' attribute can be found
553in <a
554href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's
555documentation</a>.</p>
556
557<p>Not only does the analyzer exploit this information when pruning false paths,
558but the compiler also takes it seriously and will generate different code (and
559possibly better optimized) under the assumption that the function does not
560return.</p>
561
562<p><b>Example</b></p>
563
564<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
565<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
566
567<pre class="code_example">
568void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
569</pre>
570
571<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
572
573<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
574'noreturn' except that it is ignored by the compiler for the purposes of code
575generation.</p>
576
577<p>This attribute is useful for annotating assertion handlers that actually
578<em>can</em> return, but for the purpose of using the analyzer we want to
579pretend that such functions do not return.</p>
580
581<p>Because this attribute is Clang-specific, its use should be conditioned with
582the use of preprocessor macros.</p>
583
584<p><b>Example</b>
585
586<pre class="code_example">
587#ifndef CLANG_ANALYZER_NORETURN
Ted Kremeneka0eabb72010-11-09 18:54:17 +0000588#if __has_feature(attribute_analyzer_noreturn)
Ted Kremenek591b9072009-06-08 21:21:24 +0000589<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
590#else
591#define CLANG_ANALYZER_NORETURN
592#endif
593
594void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
595</pre>
596
597</div>
Ted Kremenek8bebc6e2010-02-09 23:05:59 +0000598</div>
Ted Kremenek591b9072009-06-08 21:21:24 +0000599</body>
600</html>
601