blob: 7d509ed5dbb1f23a4a4362603161cd8dc51460fa [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}
93
94<span class="command">$ clang --analyze test.m</span>
95test.m:4:16: warning: Null pointer passed as an argument to a 'nonnull' parameter
96 return !p ? bar(q, 2, p)
97 ^ ~
981 diagnostic generated.
99</pre>
100
101<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
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
156#ifndef NS_RETURNS_RETAINED
157#if __clang__
158<span class="code_highlight">#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))</span>
159#else
160#define NS_RETURNS_RETAINED
161#endif
162#endif
163
164@interface MyClass : NSObject {}
165- (NSString*) returnsRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
166- (NSString*) alsoReturnsRetained;
167@end
168
169@implementation MyClass
170- (NSString*) returnsRetained {
171 return [[NSString alloc] initWithCString:"no leak here"];
172}
173- (NSString*) alsoReturnsRetained {
174 return [[NSString alloc] initWithCString:"flag a leak"];
175}
176@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000177</pre>
178
Ted Kremenek7d277e22009-06-24 18:50:14 +0000179<p>Running <tt>scan-build</tt> on this source file produces the following output:</p>
180
181<img src="images/example_ns_returns_retained.png">
182
Ted Kremenek591b9072009-06-08 21:21:24 +0000183<h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
184(Clang-specific)</h4>
185
186<p>The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to
187annotate an Objective-C method or C function as returning a retained Core
188Foundation object that the caller is responsible for releasing.
189
190<p><b>Placing on Objective-C methods</b>: With respect to Objective-C methods.,
191this attribute is identical in its behavior and usage to 'ns_returns_retained'
192except for the distinction of returning a Core Foundation object instead of a
193Cocoa object. This distinction is important for two reasons:</p>
194
195<ul>
196 <li>Core Foundation objects are not automatically managed by the Objective-C
197 garbage collector.</li>
198 <li>Because Core Foundation is a C API, the analyzer cannot always tell that a
199 pointer return value refers to a Core Foundation object. In contrast, it is
200 trivial for the analyzer to recognize if a pointer refers to a Cocoa object
201 (given the Objective-C type system).</p>
202</ul>
203
204<p><b>Placing on C functions</b>: When placing the attribute
205'cf_returns_retained' on the declarations of C functions, the analyzer
206interprets the function as:</p>
207
208<ol>
209 <li>Returning a Core Foundation Object</li>
210 <li>Treating the function as if it its name
211contained the keywords &quot;create&quot; or &quot;copy&quot;. This means the
212returned object as a +1 retain count that must be released by the caller, either
213by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C
214object pointer), calling <tt>CFRelease</tt> (or similar function), or using
215<tt>CFMakeCollectable</tt> to register the object with the Objective-C garbage
216collector.</li>
217</ol>
218
219<p><b>Example</b></p>
220
221<p>In this example, observe the difference in output when the code is compiled
222to not use garbage collection versus when it is compiled to only use garbage
223collection (<tt>-fobjc-gc-only</tt>).</p>
224
225<pre class="code_example">
226<span class="command">$ cat test.m</span>
227$ cat test.m
228#import &lt;Cocoa/Cocoa.h&gt;
229
230#ifndef CF_RETURNS_RETAINED
231#if __clang__
232<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
233#else
234#define CF_RETURNS_RETAINED
235#endif
236#endif
237
238@interface MyClass : NSObject {}
239- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
240- (NSDate*) alsoReturnsRetained;
241- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
242@end
243
244<span class="code_highlight">CF_RETURNS_RETAINED</span>
245CFDateRef returnsRetainedCFDate() {
246 return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
247}
248
249@implementation MyClass
250- (NSDate*) returnsCFRetained {
251 return (NSDate*) returnsRetainedCFDate(); // No leak.
252}
253
254- (NSDate*) alsoReturnsRetained {
255 return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
256}
257
258- (NSDate*) returnsNSRetained {
259 return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC.
260}
261@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000262</pre>
263
Ted Kremenek6fe1ef22009-06-24 19:04:37 +0000264<p>Running <tt>scan-build</tt> on this example produces the following output:</p>
265
266<img src="images/example_cf_returns_retained.png">
267
268</p>When the above code is compiled using Objective-C garbage collection (i.e.,
269code is compiled with the flag <tt>-fobjc-gc</tt> or <tt>-fobjc-gc-only</tt>),
270<tt>scan-build</tt> produces both the above error (with slightly different text
271to indicate the code uses garbage collection) as well as the following warning,
272which indicates a leak that occurs <em>only</em> when using garbage
273collection:</p>
274
275<img src="images/example_cf_returns_retained_gc.png">
276
Ted Kremenek591b9072009-06-08 21:21:24 +0000277<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
278<h2 id="custom_assertions">Custom Assertion Handlers</h2>
279<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
280
281<p>The analyzer exploits code assertions by pruning off paths where the
282assertion condition is false. The idea is capture any program invariants
283specified in the assertion that the developer may know but is not immediately
284apparent in the code itself. In this way assertions make implicit assumptions
285explicit in the code, which not only makes the analyzer more accurate when
286finding bugs, but can help others better able to understand your code as well.
287It can also help remove certain kinds of analyzer false positives by pruning off
288false paths.</p>
289
290<p>In order to exploit assertions, however, the analyzer must understand when it
291encounters an &quot;assertion handler.&quot; Typically assertions are
292implemented with a macro, with the macro performing a check for the assertion
293condition and, when the check fails, calling an assertion handler. For example, consider the following code
294fragment:</p>
295
296<pre class="code_example">
297void foo(int *p) {
298 assert(p != NULL);
299}
300</pre>
301
302<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
303
304<pre class="code_example">
305void foo(int *p) {
306 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
307}
308</pre>
309
310<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
311most assertion handlers typically print an error and terminate the program. The
312analyzer can exploit such semantics by ending the analysis of a path once it
313hits a call to an assertion handler.</p>
314
315<p>The trick, however, is that the analyzer needs to know that a called function
316is an assertion handler; otherwise the analyzer might assume the function call
317returns and it will continue analyzing the path where the assertion condition
318failed. This can lead to false positives, as the assertion condition usually
319implies a safety condition (e.g., a pointer is not null) prior to performing
320some action that depends on that condition (e.g., dereferencing a pointer).</p>
321
322<p>The analyzer knows about several well-known assertion handlers, but can
323automatically infer if a function should be treated as an assertion handler if
324it is annotated with the 'noreturn' attribute or the (Clang-specific)
325'analyzer_noreturn' attribute.</p>
326
327<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
328
329<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
330declarations of functions. It means exactly what its name implies: a function
331with a 'noreturn' attribute should never return.</p>
332
333<p>Specific details of the syntax of using the 'noreturn' attribute can be found
334in <a
335href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's
336documentation</a>.</p>
337
338<p>Not only does the analyzer exploit this information when pruning false paths,
339but the compiler also takes it seriously and will generate different code (and
340possibly better optimized) under the assumption that the function does not
341return.</p>
342
343<p><b>Example</b></p>
344
345<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
346<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
347
348<pre class="code_example">
349void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
350</pre>
351
352<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
353
354<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
355'noreturn' except that it is ignored by the compiler for the purposes of code
356generation.</p>
357
358<p>This attribute is useful for annotating assertion handlers that actually
359<em>can</em> return, but for the purpose of using the analyzer we want to
360pretend that such functions do not return.</p>
361
362<p>Because this attribute is Clang-specific, its use should be conditioned with
363the use of preprocessor macros.</p>
364
365<p><b>Example</b>
366
367<pre class="code_example">
368#ifndef CLANG_ANALYZER_NORETURN
369#if __clang__
370<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
371#else
372#define CLANG_ANALYZER_NORETURN
373#endif
374
375void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
376</pre>
377
378</div>
379</body>
380</html>
381