blob: 129748e9b0cc76fca77ba3ada11e28642da0a906 [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
177
178<span class="command">$ clang --analyze test.m</span>
179$ clang --analyze test.m
180test.m:21:10: warning: Potential leak of an object allocated on line 21
181 return [[NSString alloc] initWithCString:"flag a leak"];
182 ^
1831 diagnostic generated.
184</pre>
185
186<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
233#ifndef CF_RETURNS_RETAINED
234#if __clang__
235<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
236#else
237#define CF_RETURNS_RETAINED
238#endif
239#endif
240
241@interface MyClass : NSObject {}
242- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
243- (NSDate*) alsoReturnsRetained;
244- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
245@end
246
247<span class="code_highlight">CF_RETURNS_RETAINED</span>
248CFDateRef returnsRetainedCFDate() {
249 return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
250}
251
252@implementation MyClass
253- (NSDate*) returnsCFRetained {
254 return (NSDate*) returnsRetainedCFDate(); // No leak.
255}
256
257- (NSDate*) alsoReturnsRetained {
258 return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
259}
260
261- (NSDate*) returnsNSRetained {
262 return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC.
263}
264@end
265
266<span class="command">$ clang --analyze test.m</span>
267test.m:28:20: warning: Potential leak of an object allocated on line 28
268 return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
269 ^
2701 diagnostic generated.
271
272<span class="command">$ clang --analyze test.m <span class="code_highlight">-fobjc-gc-only</span></span>
273test.m:28:20: warning: Potential leak (when using garbage collection) of an object allocated on line 28
274 return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
275 ^
276test.m:32:20: warning: Potential leak (when using garbage collection) of an object allocated on line 32
277 return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC.
278 ^
2792 diagnostics generated.
280</pre>
281
282<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
283<h2 id="custom_assertions">Custom Assertion Handlers</h2>
284<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
285
286<p>The analyzer exploits code assertions by pruning off paths where the
287assertion condition is false. The idea is capture any program invariants
288specified in the assertion that the developer may know but is not immediately
289apparent in the code itself. In this way assertions make implicit assumptions
290explicit in the code, which not only makes the analyzer more accurate when
291finding bugs, but can help others better able to understand your code as well.
292It can also help remove certain kinds of analyzer false positives by pruning off
293false paths.</p>
294
295<p>In order to exploit assertions, however, the analyzer must understand when it
296encounters an &quot;assertion handler.&quot; Typically assertions are
297implemented with a macro, with the macro performing a check for the assertion
298condition and, when the check fails, calling an assertion handler. For example, consider the following code
299fragment:</p>
300
301<pre class="code_example">
302void foo(int *p) {
303 assert(p != NULL);
304}
305</pre>
306
307<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
308
309<pre class="code_example">
310void foo(int *p) {
311 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
312}
313</pre>
314
315<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
316most assertion handlers typically print an error and terminate the program. The
317analyzer can exploit such semantics by ending the analysis of a path once it
318hits a call to an assertion handler.</p>
319
320<p>The trick, however, is that the analyzer needs to know that a called function
321is an assertion handler; otherwise the analyzer might assume the function call
322returns and it will continue analyzing the path where the assertion condition
323failed. This can lead to false positives, as the assertion condition usually
324implies a safety condition (e.g., a pointer is not null) prior to performing
325some action that depends on that condition (e.g., dereferencing a pointer).</p>
326
327<p>The analyzer knows about several well-known assertion handlers, but can
328automatically infer if a function should be treated as an assertion handler if
329it is annotated with the 'noreturn' attribute or the (Clang-specific)
330'analyzer_noreturn' attribute.</p>
331
332<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
333
334<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
335declarations of functions. It means exactly what its name implies: a function
336with a 'noreturn' attribute should never return.</p>
337
338<p>Specific details of the syntax of using the 'noreturn' attribute can be found
339in <a
340href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's
341documentation</a>.</p>
342
343<p>Not only does the analyzer exploit this information when pruning false paths,
344but the compiler also takes it seriously and will generate different code (and
345possibly better optimized) under the assumption that the function does not
346return.</p>
347
348<p><b>Example</b></p>
349
350<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
351<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
352
353<pre class="code_example">
354void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
355</pre>
356
357<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
358
359<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
360'noreturn' except that it is ignored by the compiler for the purposes of code
361generation.</p>
362
363<p>This attribute is useful for annotating assertion handlers that actually
364<em>can</em> return, but for the purpose of using the analyzer we want to
365pretend that such functions do not return.</p>
366
367<p>Because this attribute is Clang-specific, its use should be conditioned with
368the use of preprocessor macros.</p>
369
370<p><b>Example</b>
371
372<pre class="code_example">
373#ifndef CLANG_ANALYZER_NORETURN
374#if __clang__
375<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
376#else
377#define CLANG_ANALYZER_NORETURN
378#endif
379
380void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
381</pre>
382
383</div>
384</body>
385</html>
386