blob: 6204713463659e62b3b56ab3a6afa04441ca6626 [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>
9 <script type="text/javascript" src="scripts/dbtree.js"></script>
Ted Kremenek591b9072009-06-08 21:21:24 +000010</head>
11<body>
12
Ted Kremenek8bebc6e2010-02-09 23:05:59 +000013<div id="page">
Ted Kremenek591b9072009-06-08 21:21:24 +000014<!--#include virtual="menu.html.incl"-->
15
16<div id="content">
17
18<h1>Source Annotations</h1>
19
20<p>The Clang frontend supports several source-level annotations in the form of
21<a href="http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html">GCC-style
22attributes</a> and pragmas that can help make using the Clang Static Analyzer
23more useful. These annotations can both help suppress false positives as well as
24enhance the analyzer's ability to find bugs.</p>
25
26<p>This page gives a practical overview of such annotations. For more technical
27specifics regarding Clang-specific annotations please see the Clang's list of <a
28href="http://clang.llvm.org/docs/LanguageExtensions.html">language
29extensions</a>. Details of &quot;standard&quot; GCC attributes (that Clang also
30supports) can be found in the <a href="http://gcc.gnu.org/onlinedocs/gcc/">GCC
31manual</a>, with the majority of the relevant attributes being in the section on
32<a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html">function
33attributes</a>.</p>
34
35<p>Note that attributes that are labeled <b>Clang-specific</b> are not
36recognized by GCC. Their use can be conditioned using preprocessor macros
37(examples included on this page).</p>
38
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000039<h4>Specific Topics</h4>
40
41<ul id="collapsetree" class="dbtree onclick multiple">
42<li><a href="#generic">Annotations to Enhance Generic Checks</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000043 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000044 <li><a href="#null_checking"><span>Null Pointer Checking</span></a>
Ted Kremenek591b9072009-06-08 21:21:24 +000045 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000046 <li><a href="#attr_nonnull"><span>Attribute 'nonnull'</span></a></li>
Ted Kremenek591b9072009-06-08 21:21:24 +000047 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000048 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000049 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000050</li>
51<li><a href="#macosx">Mac OS X API Annotations</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000052 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000053 <li><a href="#cocoa_mem">Cocoa &amp; Core Foundation Memory Management Annotations</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000054 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000055 <li><a href="#attr_ns_returns_retained">Attribute 'ns_returns_retained'</a></li>
56 <li><a href="#attr_cf_returns_retained">Attribute 'cf_returns_retained'</a></li>
57 </ul>
58 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000059 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000060</li>
61<li><a href="#custom_assertions">Custom Assertion Handlers</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000062 <ul>
63 <li><a href="#attr_noreturn">Attribute 'noreturn'</a></li>
64 <li><a href="#attr_analyzer_noreturn">Attribute 'analyzer_noreturn'</a></li>
65 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000066 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000067</ul>
68
69<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
70<h2 id="generic">Annotations to Enhance Generic Checks</h2>
71<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
72
73<h3 id="null_checking">Null Pointer Checking</h3>
74
75<h4 id="attr_nonnull">Attribute 'nonnull'</h4>
76
77<p>The analyzer recognizes the GCC attribute 'nonnull', which indicates that a
78function expects that a given function parameter is not a null pointer. Specific
79details of the syntax of using the 'nonnull' attribute can be found in <a
80href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-2263">GCC's
81documentation</a>.</p>
82
83<p>Both the Clang compiler and GCC will flag warnings for simple cases where a
84null pointer is directly being passed to a function with a 'nonnull' parameter
85(e.g., as a constant). The analyzer extends this checking by using its deeper
86symbolic analysis to track what pointer values are potentially null and then
87flag warnings when they are passed in a function call via a 'nonnull'
88parameter.</p>
89
90<p><b>Example</b></p>
91
92<pre class="code_example">
93<span class="command">$ cat test.m</span>
94int bar(int*p, int q, int *r) __attribute__((nonnull(1,3)));
95
96int foo(int *p, int *q) {
97 return !p ? bar(q, 2, p)
98 : bar(p, 2, q);
99}
Ted Kremenek591b9072009-06-08 21:21:24 +0000100</pre>
101
Ted Kremenek42291dd2009-06-24 19:17:54 +0000102<p>Running <tt>scan-build</tt> over this source produces the following
103output:</p>
104
Ted Kremenek5ceab862009-06-24 19:20:24 +0000105<img src="images/example_attribute_nonnull.png">
Ted Kremenek42291dd2009-06-24 19:17:54 +0000106
Ted Kremenek591b9072009-06-08 21:21:24 +0000107<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
108<h2 id="macosx">Mac OS X API Annotations</h2>
109<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
110
111<h3 id="cocoa_mem">Cocoa &amp; Core Foundation Memory Management
112Annotations</h3>
113
Ted Kremenekcb41f3e2009-06-09 01:32:41 +0000114<!--
Ted Kremenek591b9072009-06-08 21:21:24 +0000115<p>As described in <a href="/available_checks.html#retain_release">Available
Ted Kremenekcb41f3e2009-06-09 01:32:41 +0000116Checks</a>,
117-->
118<p>The analyzer supports the proper management of retain counts for
Ted Kremenek591b9072009-06-08 21:21:24 +0000119both Cocoa and Core Foundation objects. This checking is largely based on
120enforcing Cocoa and Core Foundation naming conventions for Objective-C methods
121(Cocoa) and C functions (Core Foundation). Not strictly following these
122conventions can cause the analyzer to miss bugs or flag false positives.</p>
123
124<p>One can educate the analyzer (and others who read your code) about methods or
125functions that deviate from the Cocoa and Core Foundation conventions using the
126attributes described here.</p>
127
128<h4 id="attr_ns_returns_retained">Attribute 'ns_returns_retained'
129(Clang-specific)</h4>
130
131<p>The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to
132annotate an Objective-C method or C function as returning a retained Cocoa
133object that the caller is responsible for releasing (via sending a
134<tt>release</tt> message to the object).</p>
135
136<p><b>Placing on Objective-C methods</b>: For Objective-C methods, this
137annotation essentially tells the analyzer to treat the method as if its name
138begins with &quot;alloc&quot; or &quot;new&quot; or contais the word
139&quot;copy&quot;.</p>
140
141<p><b>Placing on C functions</b>: For C functions returning Cocoa objects, the
142analyzer typically does not make any assumptions about whether or not the object
143is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C
144functions allows the analyzer to perform extra checking.</p>
145
146<p><b>Important note when using Garbage Collection</b>: Note that the analyzer
147interprets this attribute slightly differently when using Objective-C garbage
148collection (available on Mac OS 10.5+). When analyzing Cocoa code that uses
149garbage collection, &quot;alloc&quot; methods are assumed to return an object
150that is managed by the garbage collector (and thus doesn't have a retain count
151the caller must balance). These same assumptions are applied to methods or
152functions annotated with 'ns_returns_retained'. If you are returning a Core
153Foundation object (which may not be managed by the garbage collector) you should
154use 'cf_returns_retained'.</p>
155
156<p><b>Example</b></p>
157
158<pre class="code_example">
159<span class="command">$ cat test.m</span>
160#import &lt;Foundation/Foundation.h&gt;
161
Ted Kremenek21375a32009-07-17 00:25:49 +0000162#ifndef __has_feature // Optional.
163#define __has_feature(x) 0 // Compatibility with non-clang compilers.
164#endif
165
Ted Kremenek591b9072009-06-08 21:21:24 +0000166#ifndef NS_RETURNS_RETAINED
Ted Kremenek21375a32009-07-17 00:25:49 +0000167#if __has_feature(attribute_ns_returns_retained)
Ted Kremenek591b9072009-06-08 21:21:24 +0000168<span class="code_highlight">#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))</span>
169#else
170#define NS_RETURNS_RETAINED
171#endif
172#endif
173
174@interface MyClass : NSObject {}
175- (NSString*) returnsRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
176- (NSString*) alsoReturnsRetained;
177@end
178
179@implementation MyClass
180- (NSString*) returnsRetained {
181 return [[NSString alloc] initWithCString:"no leak here"];
182}
183- (NSString*) alsoReturnsRetained {
184 return [[NSString alloc] initWithCString:"flag a leak"];
185}
186@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000187</pre>
188
Ted Kremenek7d277e22009-06-24 18:50:14 +0000189<p>Running <tt>scan-build</tt> on this source file produces the following output:</p>
190
191<img src="images/example_ns_returns_retained.png">
192
Ted Kremenek591b9072009-06-08 21:21:24 +0000193<h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
194(Clang-specific)</h4>
195
196<p>The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to
197annotate an Objective-C method or C function as returning a retained Core
198Foundation object that the caller is responsible for releasing.
199
200<p><b>Placing on Objective-C methods</b>: With respect to Objective-C methods.,
201this attribute is identical in its behavior and usage to 'ns_returns_retained'
202except for the distinction of returning a Core Foundation object instead of a
203Cocoa object. This distinction is important for two reasons:</p>
204
205<ul>
206 <li>Core Foundation objects are not automatically managed by the Objective-C
207 garbage collector.</li>
208 <li>Because Core Foundation is a C API, the analyzer cannot always tell that a
209 pointer return value refers to a Core Foundation object. In contrast, it is
210 trivial for the analyzer to recognize if a pointer refers to a Cocoa object
211 (given the Objective-C type system).</p>
212</ul>
213
214<p><b>Placing on C functions</b>: When placing the attribute
215'cf_returns_retained' on the declarations of C functions, the analyzer
216interprets the function as:</p>
217
218<ol>
219 <li>Returning a Core Foundation Object</li>
220 <li>Treating the function as if it its name
221contained the keywords &quot;create&quot; or &quot;copy&quot;. This means the
222returned object as a +1 retain count that must be released by the caller, either
223by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C
224object pointer), calling <tt>CFRelease</tt> (or similar function), or using
225<tt>CFMakeCollectable</tt> to register the object with the Objective-C garbage
226collector.</li>
227</ol>
228
229<p><b>Example</b></p>
230
231<p>In this example, observe the difference in output when the code is compiled
232to not use garbage collection versus when it is compiled to only use garbage
233collection (<tt>-fobjc-gc-only</tt>).</p>
234
235<pre class="code_example">
236<span class="command">$ cat test.m</span>
237$ cat test.m
238#import &lt;Cocoa/Cocoa.h&gt;
239
Ted Kremenek21375a32009-07-17 00:25:49 +0000240#ifndef __has_feature // Optional.
241#define __has_feature(x) 0 // Compatibility with non-clang compilers.
242#endif
243
Ted Kremenek591b9072009-06-08 21:21:24 +0000244#ifndef CF_RETURNS_RETAINED
Ted Kremenek21375a32009-07-17 00:25:49 +0000245#if __has_feature(attribute_cf_returns_retained)
Ted Kremenek591b9072009-06-08 21:21:24 +0000246<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
247#else
248#define CF_RETURNS_RETAINED
249#endif
250#endif
251
252@interface MyClass : NSObject {}
253- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
254- (NSDate*) alsoReturnsRetained;
255- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
256@end
257
258<span class="code_highlight">CF_RETURNS_RETAINED</span>
259CFDateRef returnsRetainedCFDate() {
260 return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
261}
262
263@implementation MyClass
264- (NSDate*) returnsCFRetained {
265 return (NSDate*) returnsRetainedCFDate(); // No leak.
266}
267
268- (NSDate*) alsoReturnsRetained {
269 return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
270}
271
272- (NSDate*) returnsNSRetained {
273 return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC.
274}
275@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000276</pre>
277
Ted Kremenek6fe1ef22009-06-24 19:04:37 +0000278<p>Running <tt>scan-build</tt> on this example produces the following output:</p>
279
280<img src="images/example_cf_returns_retained.png">
281
282</p>When the above code is compiled using Objective-C garbage collection (i.e.,
283code is compiled with the flag <tt>-fobjc-gc</tt> or <tt>-fobjc-gc-only</tt>),
284<tt>scan-build</tt> produces both the above error (with slightly different text
285to indicate the code uses garbage collection) as well as the following warning,
286which indicates a leak that occurs <em>only</em> when using garbage
287collection:</p>
288
289<img src="images/example_cf_returns_retained_gc.png">
290
Ted Kremenek591b9072009-06-08 21:21:24 +0000291<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
292<h2 id="custom_assertions">Custom Assertion Handlers</h2>
293<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
294
295<p>The analyzer exploits code assertions by pruning off paths where the
296assertion condition is false. The idea is capture any program invariants
297specified in the assertion that the developer may know but is not immediately
298apparent in the code itself. In this way assertions make implicit assumptions
299explicit in the code, which not only makes the analyzer more accurate when
300finding bugs, but can help others better able to understand your code as well.
301It can also help remove certain kinds of analyzer false positives by pruning off
302false paths.</p>
303
304<p>In order to exploit assertions, however, the analyzer must understand when it
305encounters an &quot;assertion handler.&quot; Typically assertions are
306implemented with a macro, with the macro performing a check for the assertion
307condition and, when the check fails, calling an assertion handler. For example, consider the following code
308fragment:</p>
309
310<pre class="code_example">
311void foo(int *p) {
312 assert(p != NULL);
313}
314</pre>
315
316<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
317
318<pre class="code_example">
319void foo(int *p) {
320 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
321}
322</pre>
323
324<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
325most assertion handlers typically print an error and terminate the program. The
326analyzer can exploit such semantics by ending the analysis of a path once it
327hits a call to an assertion handler.</p>
328
329<p>The trick, however, is that the analyzer needs to know that a called function
330is an assertion handler; otherwise the analyzer might assume the function call
331returns and it will continue analyzing the path where the assertion condition
332failed. This can lead to false positives, as the assertion condition usually
333implies a safety condition (e.g., a pointer is not null) prior to performing
334some action that depends on that condition (e.g., dereferencing a pointer).</p>
335
336<p>The analyzer knows about several well-known assertion handlers, but can
337automatically infer if a function should be treated as an assertion handler if
338it is annotated with the 'noreturn' attribute or the (Clang-specific)
339'analyzer_noreturn' attribute.</p>
340
341<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
342
343<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
344declarations of functions. It means exactly what its name implies: a function
345with a 'noreturn' attribute should never return.</p>
346
347<p>Specific details of the syntax of using the 'noreturn' attribute can be found
348in <a
349href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's
350documentation</a>.</p>
351
352<p>Not only does the analyzer exploit this information when pruning false paths,
353but the compiler also takes it seriously and will generate different code (and
354possibly better optimized) under the assumption that the function does not
355return.</p>
356
357<p><b>Example</b></p>
358
359<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
360<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
361
362<pre class="code_example">
363void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
364</pre>
365
366<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
367
368<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
369'noreturn' except that it is ignored by the compiler for the purposes of code
370generation.</p>
371
372<p>This attribute is useful for annotating assertion handlers that actually
373<em>can</em> return, but for the purpose of using the analyzer we want to
374pretend that such functions do not return.</p>
375
376<p>Because this attribute is Clang-specific, its use should be conditioned with
377the use of preprocessor macros.</p>
378
379<p><b>Example</b>
380
381<pre class="code_example">
382#ifndef CLANG_ANALYZER_NORETURN
383#if __clang__
384<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
385#else
386#define CLANG_ANALYZER_NORETURN
387#endif
388
389void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
390</pre>
391
392</div>
Ted Kremenek8bebc6e2010-02-09 23:05:59 +0000393</div>
Ted Kremenek591b9072009-06-08 21:21:24 +0000394</body>
395</html>
396