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