blob: a08573a4c109925deb5157f7b28d2bd8386d69ec [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 Kremenekf4aed5f2010-02-12 21:05:44 +00008 <script type="text/javascript" src="scripts/menu.js"></script>
9 <script type="text/javascript" src="scripts/dbtree.js"></script>
Ted Kremenek591b9072009-06-08 21:21:24 +000010</head>
11<body>
12
Ted Kremenek8bebc6e2010-02-09 23:05:59 +000013<div id="page">
Ted Kremenek591b9072009-06-08 21:21:24 +000014<!--#include virtual="menu.html.incl"-->
15
16<div id="content">
17
18<h1>Source Annotations</h1>
19
20<p>The Clang frontend supports several source-level annotations in the form of
21<a href="http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html">GCC-style
22attributes</a> and pragmas that can help make using the Clang Static Analyzer
23more useful. These annotations can both help suppress false positives as well as
24enhance the analyzer's ability to find bugs.</p>
25
26<p>This page gives a practical overview of such annotations. For more technical
27specifics regarding Clang-specific annotations please see the Clang's list of <a
28href="http://clang.llvm.org/docs/LanguageExtensions.html">language
29extensions</a>. Details of &quot;standard&quot; GCC attributes (that Clang also
30supports) can be found in the <a href="http://gcc.gnu.org/onlinedocs/gcc/">GCC
31manual</a>, with the majority of the relevant attributes being in the section on
32<a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html">function
33attributes</a>.</p>
34
35<p>Note that attributes that are labeled <b>Clang-specific</b> are not
36recognized by GCC. Their use can be conditioned using preprocessor macros
37(examples included on this page).</p>
38
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000039<h4>Specific Topics</h4>
40
41<ul id="collapsetree" class="dbtree onclick multiple">
42<li><a href="#generic">Annotations to Enhance Generic Checks</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000043 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000044 <li><a href="#null_checking"><span>Null Pointer Checking</span></a>
Ted Kremenek591b9072009-06-08 21:21:24 +000045 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000046 <li><a href="#attr_nonnull"><span>Attribute 'nonnull'</span></a></li>
Ted Kremenek591b9072009-06-08 21:21:24 +000047 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000048 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000049 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000050</li>
51<li><a href="#macosx">Mac OS X API Annotations</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000052 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000053 <li><a href="#cocoa_mem">Cocoa &amp; Core Foundation Memory Management Annotations</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000054 <ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000055 <li><a href="#attr_ns_returns_retained">Attribute 'ns_returns_retained'</a></li>
Ted Kremeneka238f872010-05-14 18:13:43 +000056 <li><a href="#attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'</a></li>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000057 <li><a href="#attr_cf_returns_retained">Attribute 'cf_returns_retained'</a></li>
Ted Kremeneka238f872010-05-14 18:13:43 +000058 <li><a href="#attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'</a></li>
Ted Kremenek12b94342011-01-27 06:54:14 +000059 <li><a href="#attr_ns_consumes_self">Attribute 'ns_consumes_self'</a></li>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000060 </ul>
61 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000062 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000063</li>
64<li><a href="#custom_assertions">Custom Assertion Handlers</a>
Ted Kremenek591b9072009-06-08 21:21:24 +000065 <ul>
66 <li><a href="#attr_noreturn">Attribute 'noreturn'</a></li>
67 <li><a href="#attr_analyzer_noreturn">Attribute 'analyzer_noreturn'</a></li>
68 </ul>
Ted Kremenekf4aed5f2010-02-12 21:05:44 +000069 </li>
Ted Kremenek591b9072009-06-08 21:21:24 +000070</ul>
71
72<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
73<h2 id="generic">Annotations to Enhance Generic Checks</h2>
74<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
75
76<h3 id="null_checking">Null Pointer Checking</h3>
77
78<h4 id="attr_nonnull">Attribute 'nonnull'</h4>
79
80<p>The analyzer recognizes the GCC attribute 'nonnull', which indicates that a
81function expects that a given function parameter is not a null pointer. Specific
82details of the syntax of using the 'nonnull' attribute can be found in <a
83href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-2263">GCC's
84documentation</a>.</p>
85
86<p>Both the Clang compiler and GCC will flag warnings for simple cases where a
87null pointer is directly being passed to a function with a 'nonnull' parameter
88(e.g., as a constant). The analyzer extends this checking by using its deeper
89symbolic analysis to track what pointer values are potentially null and then
90flag warnings when they are passed in a function call via a 'nonnull'
91parameter.</p>
92
93<p><b>Example</b></p>
94
95<pre class="code_example">
96<span class="command">$ cat test.m</span>
97int bar(int*p, int q, int *r) __attribute__((nonnull(1,3)));
98
99int foo(int *p, int *q) {
100 return !p ? bar(q, 2, p)
101 : bar(p, 2, q);
102}
Ted Kremenek591b9072009-06-08 21:21:24 +0000103</pre>
104
Ted Kremenek42291dd2009-06-24 19:17:54 +0000105<p>Running <tt>scan-build</tt> over this source produces the following
106output:</p>
107
Ted Kremenek5ceab862009-06-24 19:20:24 +0000108<img src="images/example_attribute_nonnull.png">
Ted Kremenek42291dd2009-06-24 19:17:54 +0000109
Ted Kremenek591b9072009-06-08 21:21:24 +0000110<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
111<h2 id="macosx">Mac OS X API Annotations</h2>
112<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
113
114<h3 id="cocoa_mem">Cocoa &amp; Core Foundation Memory Management
115Annotations</h3>
116
Ted Kremenekcb41f3e2009-06-09 01:32:41 +0000117<!--
Ted Kremenek591b9072009-06-08 21:21:24 +0000118<p>As described in <a href="/available_checks.html#retain_release">Available
Ted Kremenekcb41f3e2009-06-09 01:32:41 +0000119Checks</a>,
120-->
121<p>The analyzer supports the proper management of retain counts for
Ted Kremenek591b9072009-06-08 21:21:24 +0000122both Cocoa and Core Foundation objects. This checking is largely based on
123enforcing Cocoa and Core Foundation naming conventions for Objective-C methods
124(Cocoa) and C functions (Core Foundation). Not strictly following these
125conventions can cause the analyzer to miss bugs or flag false positives.</p>
126
127<p>One can educate the analyzer (and others who read your code) about methods or
128functions that deviate from the Cocoa and Core Foundation conventions using the
129attributes described here.</p>
130
131<h4 id="attr_ns_returns_retained">Attribute 'ns_returns_retained'
132(Clang-specific)</h4>
133
134<p>The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to
135annotate an Objective-C method or C function as returning a retained Cocoa
136object that the caller is responsible for releasing (via sending a
137<tt>release</tt> message to the object).</p>
138
139<p><b>Placing on Objective-C methods</b>: For Objective-C methods, this
140annotation essentially tells the analyzer to treat the method as if its name
141begins with &quot;alloc&quot; or &quot;new&quot; or contais the word
142&quot;copy&quot;.</p>
143
144<p><b>Placing on C functions</b>: For C functions returning Cocoa objects, the
145analyzer typically does not make any assumptions about whether or not the object
146is returned retained. Explicitly adding the 'ns_returns_retained' attribute to C
147functions allows the analyzer to perform extra checking.</p>
148
149<p><b>Important note when using Garbage Collection</b>: Note that the analyzer
150interprets this attribute slightly differently when using Objective-C garbage
151collection (available on Mac OS 10.5+). When analyzing Cocoa code that uses
152garbage collection, &quot;alloc&quot; methods are assumed to return an object
153that is managed by the garbage collector (and thus doesn't have a retain count
154the caller must balance). These same assumptions are applied to methods or
155functions annotated with 'ns_returns_retained'. If you are returning a Core
156Foundation object (which may not be managed by the garbage collector) you should
157use 'cf_returns_retained'.</p>
158
159<p><b>Example</b></p>
160
161<pre class="code_example">
162<span class="command">$ cat test.m</span>
163#import &lt;Foundation/Foundation.h&gt;
164
Ted Kremenek21375a32009-07-17 00:25:49 +0000165#ifndef __has_feature // Optional.
166#define __has_feature(x) 0 // Compatibility with non-clang compilers.
167#endif
168
Ted Kremenek591b9072009-06-08 21:21:24 +0000169#ifndef NS_RETURNS_RETAINED
Ted Kremenek21375a32009-07-17 00:25:49 +0000170#if __has_feature(attribute_ns_returns_retained)
Ted Kremenek591b9072009-06-08 21:21:24 +0000171<span class="code_highlight">#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))</span>
172#else
173#define NS_RETURNS_RETAINED
174#endif
175#endif
176
177@interface MyClass : NSObject {}
178- (NSString*) returnsRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
179- (NSString*) alsoReturnsRetained;
180@end
181
182@implementation MyClass
183- (NSString*) returnsRetained {
184 return [[NSString alloc] initWithCString:"no leak here"];
185}
186- (NSString*) alsoReturnsRetained {
187 return [[NSString alloc] initWithCString:"flag a leak"];
188}
189@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000190</pre>
191
Ted Kremenek7d277e22009-06-24 18:50:14 +0000192<p>Running <tt>scan-build</tt> on this source file produces the following output:</p>
193
194<img src="images/example_ns_returns_retained.png">
195
Ted Kremeneka238f872010-05-14 18:13:43 +0000196<h4 id="attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'
197(Clang-specific)</h4>
198
199<p>The 'ns_returns_not_retained' attribute is the complement of '<a
200href="#attr_ns_returns_retained">ns_returns_retained</a>'. Where a function or
201method may appear to obey the Cocoa conventions and return a retained Cocoa
202object, this attribute can be used to indicate that the object reference
203returned should not be considered as an &quot;owning&quot; reference being
204returned to the caller.</p>
205
206<p>Usage is identical to <a
207href="#attr_ns_returns_retained">ns_returns_retained</a>. When using the
208attribute, be sure to declare it within the proper macro that checks for
209its availability, as it is not available in earlier versions of the analyzer:</p>
210
211<pre class="code_example">
212<span class="command">$ cat test.m</span>
213#ifndef __has_feature // Optional.
214#define __has_feature(x) 0 // Compatibility with non-clang compilers.
215#endif
216
217#ifndef NS_RETURNS_NOT_RETAINED
218#if __has_feature(attribute_ns_returns_not_retained)
219<span class="code_highlight">#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))</span>
220#else
221#define NS_RETURNS_NOT_RETAINED
222#endif
223#endif
224</pre>
225
Ted Kremenek591b9072009-06-08 21:21:24 +0000226<h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
227(Clang-specific)</h4>
228
229<p>The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to
230annotate an Objective-C method or C function as returning a retained Core
231Foundation object that the caller is responsible for releasing.
232
233<p><b>Placing on Objective-C methods</b>: With respect to Objective-C methods.,
234this attribute is identical in its behavior and usage to 'ns_returns_retained'
235except for the distinction of returning a Core Foundation object instead of a
236Cocoa object. This distinction is important for two reasons:</p>
237
238<ul>
239 <li>Core Foundation objects are not automatically managed by the Objective-C
240 garbage collector.</li>
241 <li>Because Core Foundation is a C API, the analyzer cannot always tell that a
242 pointer return value refers to a Core Foundation object. In contrast, it is
243 trivial for the analyzer to recognize if a pointer refers to a Cocoa object
244 (given the Objective-C type system).</p>
245</ul>
246
247<p><b>Placing on C functions</b>: When placing the attribute
248'cf_returns_retained' on the declarations of C functions, the analyzer
249interprets the function as:</p>
250
251<ol>
252 <li>Returning a Core Foundation Object</li>
253 <li>Treating the function as if it its name
254contained the keywords &quot;create&quot; or &quot;copy&quot;. This means the
255returned object as a +1 retain count that must be released by the caller, either
256by sending a <tt>release</tt> message (via toll-free bridging to an Objective-C
257object pointer), calling <tt>CFRelease</tt> (or similar function), or using
258<tt>CFMakeCollectable</tt> to register the object with the Objective-C garbage
259collector.</li>
260</ol>
261
262<p><b>Example</b></p>
263
264<p>In this example, observe the difference in output when the code is compiled
265to not use garbage collection versus when it is compiled to only use garbage
266collection (<tt>-fobjc-gc-only</tt>).</p>
267
268<pre class="code_example">
269<span class="command">$ cat test.m</span>
270$ cat test.m
271#import &lt;Cocoa/Cocoa.h&gt;
272
Ted Kremenek21375a32009-07-17 00:25:49 +0000273#ifndef __has_feature // Optional.
274#define __has_feature(x) 0 // Compatibility with non-clang compilers.
275#endif
276
Ted Kremenek591b9072009-06-08 21:21:24 +0000277#ifndef CF_RETURNS_RETAINED
Ted Kremenek21375a32009-07-17 00:25:49 +0000278#if __has_feature(attribute_cf_returns_retained)
Ted Kremenek591b9072009-06-08 21:21:24 +0000279<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
280#else
281#define CF_RETURNS_RETAINED
282#endif
283#endif
284
285@interface MyClass : NSObject {}
286- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
287- (NSDate*) alsoReturnsRetained;
288- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
289@end
290
291<span class="code_highlight">CF_RETURNS_RETAINED</span>
292CFDateRef returnsRetainedCFDate() {
293 return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
294}
295
296@implementation MyClass
297- (NSDate*) returnsCFRetained {
298 return (NSDate*) returnsRetainedCFDate(); // No leak.
299}
300
301- (NSDate*) alsoReturnsRetained {
302 return (NSDate*) returnsRetainedCFDate(); // Always report a leak.
303}
304
305- (NSDate*) returnsNSRetained {
306 return (NSDate*) returnsRetainedCFDate(); // Report a leak when using GC.
307}
308@end
Ted Kremenek591b9072009-06-08 21:21:24 +0000309</pre>
310
Ted Kremenek6fe1ef22009-06-24 19:04:37 +0000311<p>Running <tt>scan-build</tt> on this example produces the following output:</p>
312
313<img src="images/example_cf_returns_retained.png">
314
315</p>When the above code is compiled using Objective-C garbage collection (i.e.,
316code is compiled with the flag <tt>-fobjc-gc</tt> or <tt>-fobjc-gc-only</tt>),
317<tt>scan-build</tt> produces both the above error (with slightly different text
318to indicate the code uses garbage collection) as well as the following warning,
319which indicates a leak that occurs <em>only</em> when using garbage
320collection:</p>
321
322<img src="images/example_cf_returns_retained_gc.png">
323
Ted Kremeneka238f872010-05-14 18:13:43 +0000324<h4 id="attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'
325(Clang-specific)</h4>
326
327<p>The 'cf_returns_not_retained' attribute is the complement of '<a
328href="#attr_cf_returns_retained">cf_returns_retained</a>'. Where a function or
329method may appear to obey the Core Foundation or Cocoa conventions and return
330a retained Core Foundation object, this attribute can be used to indicate that
331the object reference returned should not be considered as an
332&quot;owning&quot; reference being returned to the caller.</p>
333
334<p>Usage is identical to <a
335href="#attr_cf_returns_retained">cf_returns_retained</a>. When using the
336attribute, be sure to declare it within the proper macro that checks for
337its availability, as it is not available in earlier versions of the analyzer:</p>
338
339<pre class="code_example">
340<span class="command">$ cat test.m</span>
341#ifndef __has_feature // Optional.
342#define __has_feature(x) 0 // Compatibility with non-clang compilers.
343#endif
344
345#ifndef CF_RETURNS_NOT_RETAINED
346#if __has_feature(attribute_cf_returns_not_retained)
347<span class="code_highlight">#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))</span>
348#else
349#define CF_RETURNS_NOT_RETAINED
350#endif
351#endif
352</pre>
353
Ted Kremenek12b94342011-01-27 06:54:14 +0000354<h4 id="attr_ns_consumes_self">Attribute 'ns_consumes_self'
355(Clang-specific)</h4>
356
357<p>The 'ns_consumes_self' attribute can be placed only on an Objective-C method declaration.
358 It indicates that the receiver of the message is &quot;consumed&quot; (a single reference count decremented)
359 after the message is sent. This matches the semantics of all &quot;init&quot; methods.
360</p>
361
362<p>One use of this attribute is declare your own init-like methods that do not follow the
363 standard Cocoa naming conventions. For example:</p>
364
365<pre class="code_example">
366#ifndef __has_feature
Ted Kremeneka018c272011-01-27 06:59:29 +0000367#define __has_feature(x) 0 // Compatibility with non-clang compilers.
Ted Kremenek12b94342011-01-27 06:54:14 +0000368#endif
369
370#ifndef NS_CONSUMES_SELF
Ted Kremeneka018c272011-01-27 06:59:29 +0000371<span class="code_highlight">#if __has_feature((attribute_ns_consumes_self))</span>
Ted Kremenek12b94342011-01-27 06:54:14 +0000372#else
373#define NS_CONSUMES_SELF
374#endif
375#endif
376
377@interface MyClass : NSObject
378- initWith:(MyClass *)x;
Ted Kremeneka018c272011-01-27 06:59:29 +0000379- nonstandardInitWith:(MyClass *)x <span class="code_highlight">NS_CONSUMES_SELF</span> NS_RETURNS_RETAINED;
Ted Kremenek12b94342011-01-27 06:54:14 +0000380@end
381</pre>
382
383<p>In this example, <tt>nonstandardInitWith:</tt> has the same ownership semantics as the init method <tt>initWith:</tt>.
384 The static analyzer will observe that the method consumes the receiver, and then returns an object with a +1 retain count.</p>
385
Ted Kremenek591b9072009-06-08 21:21:24 +0000386<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
387<h2 id="custom_assertions">Custom Assertion Handlers</h2>
388<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
389
390<p>The analyzer exploits code assertions by pruning off paths where the
391assertion condition is false. The idea is capture any program invariants
392specified in the assertion that the developer may know but is not immediately
393apparent in the code itself. In this way assertions make implicit assumptions
394explicit in the code, which not only makes the analyzer more accurate when
395finding bugs, but can help others better able to understand your code as well.
396It can also help remove certain kinds of analyzer false positives by pruning off
397false paths.</p>
398
399<p>In order to exploit assertions, however, the analyzer must understand when it
400encounters an &quot;assertion handler.&quot; Typically assertions are
401implemented with a macro, with the macro performing a check for the assertion
402condition and, when the check fails, calling an assertion handler. For example, consider the following code
403fragment:</p>
404
405<pre class="code_example">
406void foo(int *p) {
407 assert(p != NULL);
408}
409</pre>
410
411<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
412
413<pre class="code_example">
414void foo(int *p) {
415 (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
416}
417</pre>
418
419<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
420most assertion handlers typically print an error and terminate the program. The
421analyzer can exploit such semantics by ending the analysis of a path once it
422hits a call to an assertion handler.</p>
423
424<p>The trick, however, is that the analyzer needs to know that a called function
425is an assertion handler; otherwise the analyzer might assume the function call
426returns and it will continue analyzing the path where the assertion condition
427failed. This can lead to false positives, as the assertion condition usually
428implies a safety condition (e.g., a pointer is not null) prior to performing
429some action that depends on that condition (e.g., dereferencing a pointer).</p>
430
431<p>The analyzer knows about several well-known assertion handlers, but can
432automatically infer if a function should be treated as an assertion handler if
433it is annotated with the 'noreturn' attribute or the (Clang-specific)
434'analyzer_noreturn' attribute.</p>
435
436<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
437
438<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
439declarations of functions. It means exactly what its name implies: a function
440with a 'noreturn' attribute should never return.</p>
441
442<p>Specific details of the syntax of using the 'noreturn' attribute can be found
443in <a
444href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2264">GCC's
445documentation</a>.</p>
446
447<p>Not only does the analyzer exploit this information when pruning false paths,
448but the compiler also takes it seriously and will generate different code (and
449possibly better optimized) under the assumption that the function does not
450return.</p>
451
452<p><b>Example</b></p>
453
454<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
455<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
456
457<pre class="code_example">
458void __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
459</pre>
460
461<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
462
463<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
464'noreturn' except that it is ignored by the compiler for the purposes of code
465generation.</p>
466
467<p>This attribute is useful for annotating assertion handlers that actually
468<em>can</em> return, but for the purpose of using the analyzer we want to
469pretend that such functions do not return.</p>
470
471<p>Because this attribute is Clang-specific, its use should be conditioned with
472the use of preprocessor macros.</p>
473
474<p><b>Example</b>
475
476<pre class="code_example">
477#ifndef CLANG_ANALYZER_NORETURN
Ted Kremeneka0eabb72010-11-09 18:54:17 +0000478#if __has_feature(attribute_analyzer_noreturn)
Ted Kremenek591b9072009-06-08 21:21:24 +0000479<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
480#else
481#define CLANG_ANALYZER_NORETURN
482#endif
483
484void my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
485</pre>
486
487</div>
Ted Kremenek8bebc6e2010-02-09 23:05:59 +0000488</div>
Ted Kremenek591b9072009-06-08 21:21:24 +0000489</body>
490</html>
491