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