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