xref: /openbsd-src/gnu/llvm/clang/www/analyzer/annotations.html (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
1*e5dd7070Spatrick<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2*e5dd7070Spatrick          "http://www.w3.org/TR/html4/strict.dtd">
3*e5dd7070Spatrick<html>
4*e5dd7070Spatrick<head>
5*e5dd7070Spatrick  <title>Source Annotations</title>
6*e5dd7070Spatrick  <link type="text/css" rel="stylesheet" href="menu.css">
7*e5dd7070Spatrick  <link type="text/css" rel="stylesheet" href="content.css">
8*e5dd7070Spatrick  <script type="text/javascript" src="scripts/menu.js"></script>
9*e5dd7070Spatrick</head>
10*e5dd7070Spatrick<body>
11*e5dd7070Spatrick
12*e5dd7070Spatrick<div id="page">
13*e5dd7070Spatrick<!--#include virtual="menu.html.incl"-->
14*e5dd7070Spatrick
15*e5dd7070Spatrick<div id="content">
16*e5dd7070Spatrick
17*e5dd7070Spatrick<h1>Source Annotations</h1>
18*e5dd7070Spatrick
19*e5dd7070Spatrick<p>The Clang frontend supports several source-level annotations in the form of
20*e5dd7070Spatrick<a href="https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html">GCC-style
21*e5dd7070Spatrickattributes</a> and pragmas that can help make using the Clang Static Analyzer
22*e5dd7070Spatrickmore useful. These annotations can both help suppress false positives as well as
23*e5dd7070Spatrickenhance the analyzer's ability to find bugs.</p>
24*e5dd7070Spatrick
25*e5dd7070Spatrick<p>This page gives a practical overview of such annotations. For more technical
26*e5dd7070Spatrickspecifics regarding Clang-specific annotations please see the Clang's list of <a
27*e5dd7070Spatrickhref="https://clang.llvm.org/docs/LanguageExtensions.html">language
28*e5dd7070Spatrickextensions</a>. Details of &quot;standard&quot; GCC attributes (that Clang also
29*e5dd7070Spatricksupports) can be found in the <a href="https://gcc.gnu.org/onlinedocs/gcc/">GCC
30*e5dd7070Spatrickmanual</a>, with the majority of the relevant attributes being in the section on
31*e5dd7070Spatrick<a href="https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html">function
32*e5dd7070Spatrickattributes</a>.</p>
33*e5dd7070Spatrick
34*e5dd7070Spatrick<p>Note that attributes that are labeled <b>Clang-specific</b> are not
35*e5dd7070Spatrickrecognized by GCC. Their use can be conditioned using preprocessor macros
36*e5dd7070Spatrick(examples included on this page).</p>
37*e5dd7070Spatrick
38*e5dd7070Spatrick<h4>Specific Topics</h4>
39*e5dd7070Spatrick
40*e5dd7070Spatrick<ul>
41*e5dd7070Spatrick<li><a href="#generic">Annotations to Enhance Generic Checks</a>
42*e5dd7070Spatrick  <ul>
43*e5dd7070Spatrick    <li><a href="#null_checking"><span>Null Pointer Checking</span></a>
44*e5dd7070Spatrick    <ul>
45*e5dd7070Spatrick      <li><a href="#attr_nonnull"><span>Attribute 'nonnull'</span></a></li>
46*e5dd7070Spatrick    </ul>
47*e5dd7070Spatrick    </li>
48*e5dd7070Spatrick  </ul>
49*e5dd7070Spatrick</li>
50*e5dd7070Spatrick<li><a href="#macosx">Mac OS X API Annotations</a>
51*e5dd7070Spatrick  <ul>
52*e5dd7070Spatrick    <li><a href="#cocoa_mem">Cocoa &amp; Core Foundation Memory Management Annotations</a>
53*e5dd7070Spatrick    <ul>
54*e5dd7070Spatrick      <li><a href="#attr_ns_returns_retained">Attribute 'ns_returns_retained'</a></li>
55*e5dd7070Spatrick      <li><a href="#attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'</a></li>
56*e5dd7070Spatrick      <li><a href="#attr_cf_returns_retained">Attribute 'cf_returns_retained'</a></li>
57*e5dd7070Spatrick      <li><a href="#attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'</a></li>
58*e5dd7070Spatrick      <li><a href="#attr_ns_consumed">Attribute 'ns_consumed'</a></li>
59*e5dd7070Spatrick      <li><a href="#attr_cf_consumed">Attribute 'cf_consumed'</a></li>
60*e5dd7070Spatrick      <li><a href="#attr_ns_consumes_self">Attribute 'ns_consumes_self'</a></li>
61*e5dd7070Spatrick    </ul>
62*e5dd7070Spatrick    </li>
63*e5dd7070Spatrick    <li><a href="#osobject_mem">Libkern Memory Management Annotations</a>
64*e5dd7070Spatrick      <ul>
65*e5dd7070Spatrick        <li><a href="#attr_os_returns_retained">Attribute 'os_returns_retained'</a></li>
66*e5dd7070Spatrick        <li><a href="#attr_os_returns_not_retained">Attribute 'os_returns_not_retained'</a></li>
67*e5dd7070Spatrick        <li><a href="#attr_os_consumed">Attribute 'os_consumed'</a></li>
68*e5dd7070Spatrick        <li><a href="#attr_os_consumes_this">Attribute 'os_consumes_this'</a></li>
69*e5dd7070Spatrick        <li><a href="#os_out_parameters">Out Parameters</a></li>
70*e5dd7070Spatrick      </ul>
71*e5dd7070Spatrick
72*e5dd7070Spatrick    </li>
73*e5dd7070Spatrick  </ul>
74*e5dd7070Spatrick</li>
75*e5dd7070Spatrick<li><a href="#custom_assertions">Custom Assertion Handlers</a>
76*e5dd7070Spatrick  <ul>
77*e5dd7070Spatrick    <li><a href="#attr_noreturn">Attribute 'noreturn'</a></li>
78*e5dd7070Spatrick    <li><a href="#attr_analyzer_noreturn">Attribute 'analyzer_noreturn'</a></li>
79*e5dd7070Spatrick  </ul>
80*e5dd7070Spatrick  </li>
81*e5dd7070Spatrick</ul>
82*e5dd7070Spatrick
83*e5dd7070Spatrick<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
84*e5dd7070Spatrick<h2 id="generic">Annotations to Enhance Generic Checks</h2>
85*e5dd7070Spatrick<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
86*e5dd7070Spatrick
87*e5dd7070Spatrick<h3 id="null_checking">Null Pointer Checking</h3>
88*e5dd7070Spatrick
89*e5dd7070Spatrick<h4 id="attr_nonnull">Attribute 'nonnull'</h4>
90*e5dd7070Spatrick
91*e5dd7070Spatrick<p>The analyzer recognizes the GCC attribute 'nonnull', which indicates that a
92*e5dd7070Spatrickfunction expects that a given function parameter is not a null pointer. Specific
93*e5dd7070Spatrickdetails of the syntax of using the 'nonnull' attribute can be found in <a
94*e5dd7070Spatrickhref="https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-nonnull-function-attribute">GCC's
95*e5dd7070Spatrickdocumentation</a>.</p>
96*e5dd7070Spatrick
97*e5dd7070Spatrick<p>Both the Clang compiler and GCC will flag warnings for simple cases where a
98*e5dd7070Spatricknull pointer is directly being passed to a function with a 'nonnull' parameter
99*e5dd7070Spatrick(e.g., as a constant). The analyzer extends this checking by using its deeper
100*e5dd7070Spatricksymbolic analysis to track what pointer values are potentially null and then
101*e5dd7070Spatrickflag warnings when they are passed in a function call via a 'nonnull'
102*e5dd7070Spatrickparameter.</p>
103*e5dd7070Spatrick
104*e5dd7070Spatrick<p><b>Example</b></p>
105*e5dd7070Spatrick
106*e5dd7070Spatrick<pre class="code_example">
107*e5dd7070Spatrick<span class="command">$ cat test.m</span>
108*e5dd7070Spatrickint bar(int*p, int q, int *r) __attribute__((nonnull(1,3)));
109*e5dd7070Spatrick
110*e5dd7070Spatrickint foo(int *p, int *q) {
111*e5dd7070Spatrick   return !p ? bar(q, 2, p)
112*e5dd7070Spatrick             : bar(p, 2, q);
113*e5dd7070Spatrick}
114*e5dd7070Spatrick</pre>
115*e5dd7070Spatrick
116*e5dd7070Spatrick<p>Running <tt>scan-build</tt> over this source produces the following
117*e5dd7070Spatrickoutput:</p>
118*e5dd7070Spatrick
119*e5dd7070Spatrick<img src="images/example_attribute_nonnull.png" alt="example attribute nonnull">
120*e5dd7070Spatrick
121*e5dd7070Spatrick<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
122*e5dd7070Spatrick<h2 id="macosx">Mac OS X API Annotations</h2>
123*e5dd7070Spatrick<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
124*e5dd7070Spatrick
125*e5dd7070Spatrick<h3 id="cocoa_mem">Cocoa &amp; Core Foundation Memory Management
126*e5dd7070SpatrickAnnotations</h3>
127*e5dd7070Spatrick
128*e5dd7070Spatrick<!--
129*e5dd7070Spatrick<p>As described in <a href="/available_checks.html#retain_release">Available
130*e5dd7070SpatrickChecks</a>,
131*e5dd7070Spatrick-->
132*e5dd7070Spatrick<p>The analyzer supports the proper management of retain counts for
133*e5dd7070Spatrickboth Cocoa and Core Foundation objects. This checking is largely based on
134*e5dd7070Spatrickenforcing Cocoa and Core Foundation naming conventions for Objective-C methods
135*e5dd7070Spatrick(Cocoa) and C functions (Core Foundation). Not strictly following these
136*e5dd7070Spatrickconventions can cause the analyzer to miss bugs or flag false positives.</p>
137*e5dd7070Spatrick
138*e5dd7070Spatrick<p>One can educate the analyzer (and others who read your code) about methods or
139*e5dd7070Spatrickfunctions that deviate from the Cocoa and Core Foundation conventions using the
140*e5dd7070Spatrickattributes described here. However, you should consider using proper naming
141*e5dd7070Spatrickconventions or the <a
142*e5dd7070Spatrickhref="https://clang.llvm.org/docs/LanguageExtensions.html#the-objc-method-family-attribute"><tt>objc_method_family</tt></a>
143*e5dd7070Spatrickattribute, if applicable.</p>
144*e5dd7070Spatrick
145*e5dd7070Spatrick<h4 id="attr_ns_returns_retained">Attribute 'ns_returns_retained'
146*e5dd7070Spatrick(Clang-specific)</h4>
147*e5dd7070Spatrick
148*e5dd7070Spatrick<p>The GCC-style (Clang-specific) attribute 'ns_returns_retained' allows one to
149*e5dd7070Spatrickannotate an Objective-C method or C function as returning a retained Cocoa
150*e5dd7070Spatrickobject that the caller is responsible for releasing (via sending a
151*e5dd7070Spatrick<tt>release</tt> message to the object). The Foundation framework defines a
152*e5dd7070Spatrickmacro <b><tt>NS_RETURNS_RETAINED</tt></b> that is functionally equivalent to the
153*e5dd7070Spatrickone shown below.</p>
154*e5dd7070Spatrick
155*e5dd7070Spatrick<p><b>Placing on Objective-C methods</b>: For Objective-C methods, this
156*e5dd7070Spatrickannotation essentially tells the analyzer to treat the method as if its name
157*e5dd7070Spatrickbegins with &quot;alloc&quot; or &quot;new&quot; or contains the word
158*e5dd7070Spatrick&quot;copy&quot;.</p>
159*e5dd7070Spatrick
160*e5dd7070Spatrick<p><b>Placing on C functions</b>: For C functions returning Cocoa objects, the
161*e5dd7070Spatrickanalyzer typically does not make any assumptions about whether or not the object
162*e5dd7070Spatrickis returned retained. Explicitly adding the 'ns_returns_retained' attribute to C
163*e5dd7070Spatrickfunctions allows the analyzer to perform extra checking.</p>
164*e5dd7070Spatrick
165*e5dd7070Spatrick<p><b>Example</b></p>
166*e5dd7070Spatrick
167*e5dd7070Spatrick<pre class="code_example">
168*e5dd7070Spatrick<span class="command">$ cat test.m</span>
169*e5dd7070Spatrick#import &lt;Foundation/Foundation.h&gt;
170*e5dd7070Spatrick
171*e5dd7070Spatrick#ifndef __has_feature      // Optional.
172*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
173*e5dd7070Spatrick#endif
174*e5dd7070Spatrick
175*e5dd7070Spatrick#ifndef NS_RETURNS_RETAINED
176*e5dd7070Spatrick#if __has_feature(attribute_ns_returns_retained)
177*e5dd7070Spatrick<span class="code_highlight">#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))</span>
178*e5dd7070Spatrick#else
179*e5dd7070Spatrick#define NS_RETURNS_RETAINED
180*e5dd7070Spatrick#endif
181*e5dd7070Spatrick#endif
182*e5dd7070Spatrick
183*e5dd7070Spatrick@interface MyClass : NSObject {}
184*e5dd7070Spatrick- (NSString*) returnsRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
185*e5dd7070Spatrick- (NSString*) alsoReturnsRetained;
186*e5dd7070Spatrick@end
187*e5dd7070Spatrick
188*e5dd7070Spatrick@implementation MyClass
189*e5dd7070Spatrick- (NSString*) returnsRetained {
190*e5dd7070Spatrick  return [[NSString alloc] initWithCString:"no leak here"];
191*e5dd7070Spatrick}
192*e5dd7070Spatrick- (NSString*) alsoReturnsRetained {
193*e5dd7070Spatrick  return [[NSString alloc] initWithCString:"flag a leak"];
194*e5dd7070Spatrick}
195*e5dd7070Spatrick@end
196*e5dd7070Spatrick</pre>
197*e5dd7070Spatrick
198*e5dd7070Spatrick<p>Running <tt>scan-build</tt> on this source file produces the following output:</p>
199*e5dd7070Spatrick
200*e5dd7070Spatrick<img src="images/example_ns_returns_retained.png" alt="example returns retained">
201*e5dd7070Spatrick
202*e5dd7070Spatrick<h4 id="attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'
203*e5dd7070Spatrick(Clang-specific)</h4>
204*e5dd7070Spatrick
205*e5dd7070Spatrick<p>The 'ns_returns_not_retained' attribute is the complement of '<a
206*e5dd7070Spatrickhref="#attr_ns_returns_retained">ns_returns_retained</a>'. Where a function or
207*e5dd7070Spatrickmethod may appear to obey the Cocoa conventions and return a retained Cocoa
208*e5dd7070Spatrickobject, this attribute can be used to indicate that the object reference
209*e5dd7070Spatrickreturned should not be considered as an &quot;owning&quot; reference being
210*e5dd7070Spatrickreturned to the caller. The Foundation framework defines a
211*e5dd7070Spatrickmacro <b><tt>NS_RETURNS_NOT_RETAINED</tt></b> that is functionally equivalent to
212*e5dd7070Spatrickthe one shown below.</p>
213*e5dd7070Spatrick
214*e5dd7070Spatrick<p>Usage is identical to <a
215*e5dd7070Spatrickhref="#attr_ns_returns_retained">ns_returns_retained</a>.  When using the
216*e5dd7070Spatrickattribute, be sure to declare it within the proper macro that checks for
217*e5dd7070Spatrickits availability, as it is not available in earlier versions of the analyzer:</p>
218*e5dd7070Spatrick
219*e5dd7070Spatrick<pre class="code_example">
220*e5dd7070Spatrick<span class="command">$ cat test.m</span>
221*e5dd7070Spatrick#ifndef __has_feature      // Optional.
222*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
223*e5dd7070Spatrick#endif
224*e5dd7070Spatrick
225*e5dd7070Spatrick#ifndef NS_RETURNS_NOT_RETAINED
226*e5dd7070Spatrick#if __has_feature(attribute_ns_returns_not_retained)
227*e5dd7070Spatrick<span class="code_highlight">#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))</span>
228*e5dd7070Spatrick#else
229*e5dd7070Spatrick#define NS_RETURNS_NOT_RETAINED
230*e5dd7070Spatrick#endif
231*e5dd7070Spatrick#endif
232*e5dd7070Spatrick</pre>
233*e5dd7070Spatrick
234*e5dd7070Spatrick<h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
235*e5dd7070Spatrick(Clang-specific)</h4>
236*e5dd7070Spatrick
237*e5dd7070Spatrick<p>The GCC-style (Clang-specific) attribute 'cf_returns_retained' allows one to
238*e5dd7070Spatrickannotate an Objective-C method or C function as returning a retained Core
239*e5dd7070SpatrickFoundation object that the caller is responsible for releasing. The
240*e5dd7070SpatrickCoreFoundation framework defines a macro <b><tt>CF_RETURNS_RETAINED</tt></b>
241*e5dd7070Spatrickthat is functionally equivalent to the one shown below.</p>
242*e5dd7070Spatrick
243*e5dd7070Spatrick<p><b>Placing on Objective-C methods</b>: With respect to Objective-C methods.,
244*e5dd7070Spatrickthis attribute is identical in its behavior and usage to 'ns_returns_retained'
245*e5dd7070Spatrickexcept for the distinction of returning a Core Foundation object instead of a
246*e5dd7070SpatrickCocoa object.
247*e5dd7070Spatrick
248*e5dd7070SpatrickThis distinction is important for the following reason:
249*e5dd7070Spatrickas Core Foundation is a C API,
250*e5dd7070Spatrickthe analyzer cannot always tell that a pointer return value refers to a
251*e5dd7070SpatrickCore Foundation object.
252*e5dd7070SpatrickIn contrast, it is
253*e5dd7070Spatricktrivial for the analyzer to recognize if a pointer refers to a Cocoa object
254*e5dd7070Spatrick(given the Objective-C type system).
255*e5dd7070Spatrick
256*e5dd7070Spatrick<p><b>Placing on C functions</b>: When placing the attribute
257*e5dd7070Spatrick'cf_returns_retained' on the declarations of C functions, the analyzer
258*e5dd7070Spatrickinterprets the function as:</p>
259*e5dd7070Spatrick
260*e5dd7070Spatrick<ol>
261*e5dd7070Spatrick  <li>Returning a Core Foundation Object</li>
262*e5dd7070Spatrick  <li>Treating the function as if it its name
263*e5dd7070Spatrickcontained the keywords &quot;create&quot; or &quot;copy&quot;. This means the
264*e5dd7070Spatrickreturned object as a +1 retain count that must be released by the caller, either
265*e5dd7070Spatrickby sending a <tt>release</tt> message (via toll-free bridging to an Objective-C
266*e5dd7070Spatrickobject pointer), or calling <tt>CFRelease</tt> or a similar function.</li>
267*e5dd7070Spatrick</ol>
268*e5dd7070Spatrick
269*e5dd7070Spatrick<p><b>Example</b></p>
270*e5dd7070Spatrick
271*e5dd7070Spatrick<pre class="code_example">
272*e5dd7070Spatrick<span class="command">$ cat test.m</span>
273*e5dd7070Spatrick$ cat test.m
274*e5dd7070Spatrick#import &lt;Cocoa/Cocoa.h&gt;
275*e5dd7070Spatrick
276*e5dd7070Spatrick#ifndef __has_feature      // Optional.
277*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
278*e5dd7070Spatrick#endif
279*e5dd7070Spatrick
280*e5dd7070Spatrick#ifndef CF_RETURNS_RETAINED
281*e5dd7070Spatrick#if __has_feature(attribute_cf_returns_retained)
282*e5dd7070Spatrick<span class="code_highlight">#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))</span>
283*e5dd7070Spatrick#else
284*e5dd7070Spatrick#define CF_RETURNS_RETAINED
285*e5dd7070Spatrick#endif
286*e5dd7070Spatrick#endif
287*e5dd7070Spatrick
288*e5dd7070Spatrick@interface MyClass : NSObject {}
289*e5dd7070Spatrick- (NSDate*) returnsCFRetained <span class="code_highlight">CF_RETURNS_RETAINED</span>;
290*e5dd7070Spatrick- (NSDate*) alsoReturnsRetained;
291*e5dd7070Spatrick- (NSDate*) returnsNSRetained <span class="code_highlight">NS_RETURNS_RETAINED</span>;
292*e5dd7070Spatrick@end
293*e5dd7070Spatrick
294*e5dd7070Spatrick<span class="code_highlight">CF_RETURNS_RETAINED</span>
295*e5dd7070SpatrickCFDateRef returnsRetainedCFDate()  {
296*e5dd7070Spatrick  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
297*e5dd7070Spatrick}
298*e5dd7070Spatrick
299*e5dd7070Spatrick@implementation MyClass
300*e5dd7070Spatrick- (NSDate*) returnsCFRetained {
301*e5dd7070Spatrick  return (NSDate*) returnsRetainedCFDate(); <b><i>// No leak.</i></b>
302*e5dd7070Spatrick}
303*e5dd7070Spatrick
304*e5dd7070Spatrick- (NSDate*) alsoReturnsRetained {
305*e5dd7070Spatrick  return (NSDate*) returnsRetainedCFDate(); <b><i>// Always report a leak.</i></b>
306*e5dd7070Spatrick}
307*e5dd7070Spatrick
308*e5dd7070Spatrick- (NSDate*) returnsNSRetained {
309*e5dd7070Spatrick  return (NSDate*) returnsRetainedCFDate(); <b><i>// Report a leak when using GC.</i></b>
310*e5dd7070Spatrick}
311*e5dd7070Spatrick@end
312*e5dd7070Spatrick</pre>
313*e5dd7070Spatrick
314*e5dd7070Spatrick<p>Running <tt>scan-build</tt> on this example produces the following output:</p>
315*e5dd7070Spatrick
316*e5dd7070Spatrick<img src="images/example_cf_returns_retained.png" alt="example returns retained">
317*e5dd7070Spatrick
318*e5dd7070Spatrick<h4 id="attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'
319*e5dd7070Spatrick(Clang-specific)</h4>
320*e5dd7070Spatrick
321*e5dd7070Spatrick<p>The 'cf_returns_not_retained' attribute is the complement of '<a
322*e5dd7070Spatrickhref="#attr_cf_returns_retained">cf_returns_retained</a>'. Where a function or
323*e5dd7070Spatrickmethod may appear to obey the Core Foundation or Cocoa conventions and return
324*e5dd7070Spatricka retained Core Foundation object, this attribute can be used to indicate that
325*e5dd7070Spatrickthe object reference returned should not be considered as an
326*e5dd7070Spatrick&quot;owning&quot; reference being returned to the caller. The
327*e5dd7070SpatrickCoreFoundation framework defines a macro <b><tt>CF_RETURNS_NOT_RETAINED</tt></b>
328*e5dd7070Spatrickthat is functionally equivalent to the one shown below.</p>
329*e5dd7070Spatrick
330*e5dd7070Spatrick<p>Usage is identical to <a
331*e5dd7070Spatrickhref="#attr_cf_returns_retained">cf_returns_retained</a>.  When using the
332*e5dd7070Spatrickattribute, be sure to declare it within the proper macro that checks for
333*e5dd7070Spatrickits availability, as it is not available in earlier versions of the analyzer:</p>
334*e5dd7070Spatrick
335*e5dd7070Spatrick<pre class="code_example">
336*e5dd7070Spatrick<span class="command">$ cat test.m</span>
337*e5dd7070Spatrick#ifndef __has_feature      // Optional.
338*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
339*e5dd7070Spatrick#endif
340*e5dd7070Spatrick
341*e5dd7070Spatrick#ifndef CF_RETURNS_NOT_RETAINED
342*e5dd7070Spatrick#if __has_feature(attribute_cf_returns_not_retained)
343*e5dd7070Spatrick<span class="code_highlight">#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))</span>
344*e5dd7070Spatrick#else
345*e5dd7070Spatrick#define CF_RETURNS_NOT_RETAINED
346*e5dd7070Spatrick#endif
347*e5dd7070Spatrick#endif
348*e5dd7070Spatrick</pre>
349*e5dd7070Spatrick
350*e5dd7070Spatrick<h4 id="attr_ns_consumed">Attribute 'ns_consumed'
351*e5dd7070Spatrick(Clang-specific)</h4>
352*e5dd7070Spatrick
353*e5dd7070Spatrick<p>The 'ns_consumed' attribute can be placed on a specific parameter in either
354*e5dd7070Spatrickthe declaration of a function or an Objective-C method. It indicates to the
355*e5dd7070Spatrickstatic analyzer that a <tt>release</tt> message is implicitly sent to the
356*e5dd7070Spatrickparameter upon completion of the call to the given function or method. The
357*e5dd7070SpatrickFoundation framework defines a macro <b><tt>NS_RELEASES_ARGUMENT</tt></b> that
358*e5dd7070Spatrickis functionally equivalent to the <tt>NS_CONSUMED</tt> macro shown below.</p>
359*e5dd7070Spatrick
360*e5dd7070Spatrick<p><b>Example</b></p>
361*e5dd7070Spatrick
362*e5dd7070Spatrick<pre class="code_example">
363*e5dd7070Spatrick<span class="command">$ cat test.m</span>
364*e5dd7070Spatrick#ifndef __has_feature      // Optional.
365*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
366*e5dd7070Spatrick#endif
367*e5dd7070Spatrick
368*e5dd7070Spatrick#ifndef NS_CONSUMED
369*e5dd7070Spatrick#if __has_feature(attribute_ns_consumed)
370*e5dd7070Spatrick<span class="code_highlight">#define NS_CONSUMED __attribute__((ns_consumed))</span>
371*e5dd7070Spatrick#else
372*e5dd7070Spatrick#define NS_CONSUMED
373*e5dd7070Spatrick#endif
374*e5dd7070Spatrick#endif
375*e5dd7070Spatrick
376*e5dd7070Spatrickvoid consume_ns(id <span class="code_highlight">NS_CONSUMED</span> x);
377*e5dd7070Spatrick
378*e5dd7070Spatrickvoid test() {
379*e5dd7070Spatrick  id x = [[NSObject alloc] init];
380*e5dd7070Spatrick  consume_ns(x); <b><i>// No leak!</i></b>
381*e5dd7070Spatrick}
382*e5dd7070Spatrick
383*e5dd7070Spatrick@interface Foo : NSObject
384*e5dd7070Spatrick+ (void) releaseArg:(id) <span class="code_highlight">NS_CONSUMED</span> x;
385*e5dd7070Spatrick+ (void) releaseSecondArg:(id)x second:(id) <span class="code_highlight">NS_CONSUMED</span> y;
386*e5dd7070Spatrick@end
387*e5dd7070Spatrick
388*e5dd7070Spatrickvoid test_method() {
389*e5dd7070Spatrick  id x = [[NSObject alloc] init];
390*e5dd7070Spatrick  [Foo releaseArg:x]; <b><i>// No leak!</i></b>
391*e5dd7070Spatrick}
392*e5dd7070Spatrick
393*e5dd7070Spatrickvoid test_method2() {
394*e5dd7070Spatrick  id a = [[NSObject alloc] init];
395*e5dd7070Spatrick  id b = [[NSObject alloc] init];
396*e5dd7070Spatrick  [Foo releaseSecondArg:a second:b]; <b><i>// 'a' is leaked, but 'b' is released.</i></b>
397*e5dd7070Spatrick}
398*e5dd7070Spatrick</pre>
399*e5dd7070Spatrick
400*e5dd7070Spatrick<h4 id="attr_cf_consumed">Attribute 'cf_consumed'
401*e5dd7070Spatrick(Clang-specific)</h4>
402*e5dd7070Spatrick
403*e5dd7070Spatrick<p>The 'cf_consumed' attribute is practically identical to <a
404*e5dd7070Spatrickhref="#attr_ns_consumed">ns_consumed</a>. The attribute can be placed on a
405*e5dd7070Spatrickspecific parameter in either the declaration of a function or an Objective-C
406*e5dd7070Spatrickmethod. It indicates to the static analyzer that the object reference is
407*e5dd7070Spatrickimplicitly passed to a call to <tt>CFRelease</tt> upon completion of the call
408*e5dd7070Spatrickto the given function or method. The CoreFoundation framework defines a macro
409*e5dd7070Spatrick<b><tt>CF_RELEASES_ARGUMENT</tt></b> that is functionally equivalent to the
410*e5dd7070Spatrick<tt>CF_CONSUMED</tt> macro shown below.</p>
411*e5dd7070Spatrick
412*e5dd7070Spatrick<p>Operationally this attribute is nearly identical to 'ns_consumed'.</p>
413*e5dd7070Spatrick
414*e5dd7070Spatrick<p><b>Example</b></p>
415*e5dd7070Spatrick
416*e5dd7070Spatrick<pre class="code_example">
417*e5dd7070Spatrick<span class="command">$ cat test.m</span>
418*e5dd7070Spatrick#ifndef __has_feature      // Optional.
419*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
420*e5dd7070Spatrick#endif
421*e5dd7070Spatrick
422*e5dd7070Spatrick#ifndef CF_CONSUMED
423*e5dd7070Spatrick#if __has_feature(attribute_cf_consumed)
424*e5dd7070Spatrick<span class="code_highlight">#define CF_CONSUMED __attribute__((cf_consumed))</span>
425*e5dd7070Spatrick#else
426*e5dd7070Spatrick#define CF_CONSUMED
427*e5dd7070Spatrick#endif
428*e5dd7070Spatrick#endif
429*e5dd7070Spatrick
430*e5dd7070Spatrickvoid consume_cf(id <span class="code_highlight">CF_CONSUMED</span> x);
431*e5dd7070Spatrickvoid consume_CFDate(CFDateRef <span class="code_highlight">CF_CONSUMED</span> x);
432*e5dd7070Spatrick
433*e5dd7070Spatrickvoid test() {
434*e5dd7070Spatrick  id x = [[NSObject alloc] init];
435*e5dd7070Spatrick  consume_cf(x); <b><i>// No leak!</i></b>
436*e5dd7070Spatrick}
437*e5dd7070Spatrick
438*e5dd7070Spatrickvoid test2() {
439*e5dd7070Spatrick  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
440*e5dd7070Spatrick  consume_CFDate(date); <b><i>// No leak, including under GC!</i></b>
441*e5dd7070Spatrick
442*e5dd7070Spatrick}
443*e5dd7070Spatrick
444*e5dd7070Spatrick@interface Foo : NSObject
445*e5dd7070Spatrick+ (void) releaseArg:(CFDateRef) <span class="code_highlight">CF_CONSUMED</span> x;
446*e5dd7070Spatrick@end
447*e5dd7070Spatrick
448*e5dd7070Spatrickvoid test_method() {
449*e5dd7070Spatrick  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
450*e5dd7070Spatrick  [Foo releaseArg:date]; <b><i>// No leak!</i></b>
451*e5dd7070Spatrick}
452*e5dd7070Spatrick</pre>
453*e5dd7070Spatrick
454*e5dd7070Spatrick<h4 id="attr_ns_consumes_self">Attribute 'ns_consumes_self'
455*e5dd7070Spatrick(Clang-specific)</h4>
456*e5dd7070Spatrick
457*e5dd7070Spatrick<p>The 'ns_consumes_self' attribute can be placed only on an Objective-C method
458*e5dd7070Spatrickdeclaration. It indicates that the receiver of the message is
459*e5dd7070Spatrick&quot;consumed&quot; (a single reference count decremented) after the message
460*e5dd7070Spatrickis sent. This matches the semantics of all &quot;init&quot; methods.</p>
461*e5dd7070Spatrick
462*e5dd7070Spatrick<p>One use of this attribute is declare your own init-like methods that do not
463*e5dd7070Spatrickfollow the standard Cocoa naming conventions.</p>
464*e5dd7070Spatrick
465*e5dd7070Spatrick<p><b>Example</b></p>
466*e5dd7070Spatrick
467*e5dd7070Spatrick<pre class="code_example">
468*e5dd7070Spatrick#ifndef __has_feature
469*e5dd7070Spatrick#define __has_feature(x) 0 // Compatibility with non-clang compilers.
470*e5dd7070Spatrick#endif
471*e5dd7070Spatrick
472*e5dd7070Spatrick#ifndef NS_CONSUMES_SELF
473*e5dd7070Spatrick#if __has_feature((attribute_ns_consumes_self))
474*e5dd7070Spatrick<span class="code_highlight">#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))</span>
475*e5dd7070Spatrick#else
476*e5dd7070Spatrick#define NS_CONSUMES_SELF
477*e5dd7070Spatrick#endif
478*e5dd7070Spatrick#endif
479*e5dd7070Spatrick
480*e5dd7070Spatrick@interface MyClass : NSObject
481*e5dd7070Spatrick- initWith:(MyClass *)x;
482*e5dd7070Spatrick- nonstandardInitWith:(MyClass *)x <span class="code_highlight">NS_CONSUMES_SELF</span> NS_RETURNS_RETAINED;
483*e5dd7070Spatrick@end
484*e5dd7070Spatrick</pre>
485*e5dd7070Spatrick
486*e5dd7070Spatrick<p>In this example, <tt>-nonstandardInitWith:</tt> has the same ownership
487*e5dd7070Spatricksemantics as the init method <tt>-initWith:</tt>. The static analyzer will
488*e5dd7070Spatrickobserve that the method consumes the receiver, and then returns an object with
489*e5dd7070Spatricka +1 retain count.</p>
490*e5dd7070Spatrick
491*e5dd7070Spatrick<p>The Foundation framework defines a macro <b><tt>NS_REPLACES_RECEIVER</tt></b>
492*e5dd7070Spatrickwhich is functionally equivalent to the combination of <tt>NS_CONSUMES_SELF</tt>
493*e5dd7070Spatrickand <tt>NS_RETURNS_RETAINED</tt> shown above.</p>
494*e5dd7070Spatrick
495*e5dd7070Spatrick<h3 id="osobject_mem">Libkern Memory Management Annotations</h3>
496*e5dd7070Spatrick
497*e5dd7070Spatrick<p><a
498*e5dd7070Spatrick  href="https://developer.apple.com/documentation/kernel/osobject?language=objc">Libkern</a>
499*e5dd7070Spatrickrequires developers to inherit all heap allocated objects from <tt>OSObject</tt>
500*e5dd7070Spatrickand to perform manual reference counting.
501*e5dd7070SpatrickThe reference counting model is very similar to MRR (manual retain-release) mode in
502*e5dd7070Spatrick<a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html">Objective-C</a>
503*e5dd7070Spatrickor to CoreFoundation reference counting.
504*e5dd7070SpatrickFreshly-allocated objects start with a reference count of 1,
505*e5dd7070Spatrickand calls to <tt>retain</tt> increment it,
506*e5dd7070Spatrickwhile calls to <tt>release</tt> decrement it.
507*e5dd7070SpatrickThe object is deallocated whenever its reference count reaches zero.</p>
508*e5dd7070Spatrick
509*e5dd7070Spatrick<p>Manually incrementing and decrementing reference counts is error-prone:
510*e5dd7070Spatrickover-retains lead to leaks, and over-releases lead to uses-after-free.
511*e5dd7070SpatrickThe analyzer can help the programmer to check for unbalanced
512*e5dd7070Spatrickretain/release calls.</p>
513*e5dd7070Spatrick
514*e5dd7070Spatrick<p>The reference count checking is based on the principle of
515*e5dd7070Spatrick<em>locality</em>: it should be possible to establish correctness
516*e5dd7070Spatrick(lack of leaks/uses after free) by looking at each function body,
517*e5dd7070Spatrickand the declarations (not the definitions) of all the functions it interacts
518*e5dd7070Spatrickwith.</p>
519*e5dd7070Spatrick
520*e5dd7070Spatrick<p>In order to support such reasoning, it should be possible to <em>summarize</em>
521*e5dd7070Spatrickthe behavior of each function, with respect to reference count
522*e5dd7070Spatrickof its returned values and attributes.</p>
523*e5dd7070Spatrick
524*e5dd7070Spatrick<p>By default, the following summaries are assumed:</p>
525*e5dd7070Spatrick<ul>
526*e5dd7070Spatrick  <li>All functions starting with <tt>get</tt> or <tt>Get</tt>,
527*e5dd7070Spatrick    unless they are returning subclasses of <tt>OSIterator</tt>,
528*e5dd7070Spatrick  are assumed to be returning at +0.
529*e5dd7070Spatrick  That is, the caller has no reference
530*e5dd7070Spatrick  count <em>obligations</em> with respect to the reference count of the returned object
531*e5dd7070Spatrick  and should leave it untouched.
532*e5dd7070Spatrick  </li>
533*e5dd7070Spatrick
534*e5dd7070Spatrick  <li>
535*e5dd7070Spatrick    All other functions are assumed to return at +1.
536*e5dd7070Spatrick    That is, the caller has an <em>obligation</em> to release such objects.
537*e5dd7070Spatrick  </li>
538*e5dd7070Spatrick
539*e5dd7070Spatrick  <li>
540*e5dd7070Spatrick    Functions are assumed not to change the reference count of their parameters,
541*e5dd7070Spatrick    including the implicit <tt>this</tt> parameter.
542*e5dd7070Spatrick  </li>
543*e5dd7070Spatrick</ul>
544*e5dd7070Spatrick
545*e5dd7070Spatrick<p>These summaries can be overriden with the following
546*e5dd7070Spatrick<a href="https://clang.llvm.org/docs/AttributeReference.html#os-returns-not-retained">attributes</a>:</p>
547*e5dd7070Spatrick
548*e5dd7070Spatrick<h4 id="attr_os_returns_retained">Attribute 'os_returns_retained'</h4>
549*e5dd7070Spatrick
550*e5dd7070Spatrick<p>The <tt>os_returns_retained</tt> attribute (accessed through the macro <tt>
551*e5dd7070SpatrickLIBKERN_RETURNS_RETAINED</tt>) plays a role identical to <a
552*e5dd7070Spatrickhref="#attr_ns_returns_retained">ns_returns_retained</a> for functions
553*e5dd7070Spatrickreturning <tt>OSObject</tt> subclasses.
554*e5dd7070SpatrickThe attribute indicates that it is a callers responsibility to release the
555*e5dd7070Spatrickreturned object.
556*e5dd7070Spatrick</p>
557*e5dd7070Spatrick
558*e5dd7070Spatrick
559*e5dd7070Spatrick<h4 id="attr_os_returns_not_retained">Attribute 'os_returns_not_retained'</h4>
560*e5dd7070Spatrick
561*e5dd7070Spatrick<p>The <tt>os_returns_not_retained</tt> attribute (accessed through the macro <tt>
562*e5dd7070SpatrickLIBKERN_RETURNS_NOT_RETAINED</tt>) plays a role identical to <a
563*e5dd7070Spatrickhref="#attr_ns_returns_not_retained">ns_returns_not_retained</a> for functions
564*e5dd7070Spatrickreturning <tt>OSObject</tt> subclasses.
565*e5dd7070SpatrickThe attribute indicates that the caller should not change the retain
566*e5dd7070Spatrickcount of the returned object.
567*e5dd7070Spatrick</p>
568*e5dd7070Spatrick
569*e5dd7070Spatrick<h5>Example</h5>
570*e5dd7070Spatrick
571*e5dd7070Spatrick<pre class="code_example">
572*e5dd7070Spatrickclass MyClass {
573*e5dd7070Spatrick  OSObject *f;
574*e5dd7070Spatrick  LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter();
575*e5dd7070Spatrick}
576*e5dd7070Spatrick
577*e5dd7070Spatrick
578*e5dd7070Spatrick// Note that the annotation only has to be applied to the function declaration.
579*e5dd7070SpatrickOSObject * MyClass::myFieldGetter() {
580*e5dd7070Spatrick  return f;
581*e5dd7070Spatrick}
582*e5dd7070Spatrick</pre>
583*e5dd7070Spatrick
584*e5dd7070Spatrick<h4 id="attr_os_consumed">Attribute 'os_consumed'</h4>
585*e5dd7070Spatrick
586*e5dd7070Spatrick<p>Similarly to <a href="#attr_ns_consumed">ns_consumed</a> attribute,
587*e5dd7070Spatrick<tt>os_consumed</tt> (accessed through <tt>LIBKERN_CONSUMED</tt>) attribute,
588*e5dd7070Spatrickapplied to a parameter,
589*e5dd7070Spatrickindicates that the call to the function <em>consumes</em> the parameter:
590*e5dd7070Spatrickthe callee should either release it or store it and release it in the destructor,
591*e5dd7070Spatrickwhile the caller should assume one is subtracted from the reference count
592*e5dd7070Spatrickafter the call.</p>
593*e5dd7070Spatrick
594*e5dd7070Spatrick<pre class="code_example">
595*e5dd7070SpatrickIOReturn addToList(LIBKERN_CONSUMED IOPMinformee *newInformee);
596*e5dd7070Spatrick</pre>
597*e5dd7070Spatrick
598*e5dd7070Spatrick<h4 id="attr_os_consumes_this">Attribute 'os_consumes_this'</h4>
599*e5dd7070Spatrick
600*e5dd7070Spatrick<p>Similarly to <a href="#attr_ns_consumes_self">ns_consumes_self</a>,
601*e5dd7070Spatrickthe <tt>os_consumes_self</tt> attribute indicates that the method call
602*e5dd7070Spatrick<em>consumes</em> the implicit <tt>this</tt> argument: the caller
603*e5dd7070Spatrickshould assume one was subtracted from the reference count of the object
604*e5dd7070Spatrickafter the call, and the callee has on obligation to either
605*e5dd7070Spatrickrelease the argument, or store it and eventually release it in the
606*e5dd7070Spatrickdestructor.</p>
607*e5dd7070Spatrick
608*e5dd7070Spatrick<pre class="code_example">
609*e5dd7070Spatrickvoid addThisToList(OSArray *givenList) LIBKERN_CONSUMES_THIS;
610*e5dd7070Spatrick</pre>
611*e5dd7070Spatrick
612*e5dd7070Spatrick<h4 id="os_out_parameters">Out Parameters</h4>
613*e5dd7070Spatrick
614*e5dd7070SpatrickA function can also return an object to a caller by a means of an out parameter
615*e5dd7070Spatrick(a pointer-to-OSObject-pointer is passed, and a callee writes a pointer to an
616*e5dd7070Spatrickobject into an argument).
617*e5dd7070SpatrickCurrently the analyzer does not track unannotated out
618*e5dd7070Spatrickparameters by default, but with annotations we distinguish four separate cases:
619*e5dd7070Spatrick
620*e5dd7070Spatrick<p><b>1. Non-retained out parameters</b>, identified using
621*e5dd7070Spatrick    <tt>LIBKERN_RETURNS_NOT_RETAINED</tt> applied to parameters, e.g.:</p>
622*e5dd7070Spatrick
623*e5dd7070Spatrick<pre class="code_example">
624*e5dd7070Spatrickvoid getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj)
625*e5dd7070Spatrick</pre>
626*e5dd7070Spatrick
627*e5dd7070Spatrick<p>Such functions write a non-retained object into an out parameter, and the
628*e5dd7070Spatrickcaller has no further obligations.</p>
629*e5dd7070Spatrick
630*e5dd7070Spatrick<p><b>2. Retained out parameters</b>,
631*e5dd7070Spatrickidentified using <tt>LIBKERN_RETURNS_RETAINED</tt>:</p>
632*e5dd7070Spatrick<pre class="code_example">
633*e5dd7070Spatrickvoid getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj)
634*e5dd7070Spatrick</pre>
635*e5dd7070Spatrick<p>
636*e5dd7070SpatrickIn such cases a retained object is written into an out parameter, which the caller has then to release in order to avoid a leak.
637*e5dd7070Spatrick</p>
638*e5dd7070Spatrick
639*e5dd7070Spatrick<p>These two cases are simple - but in practice a functions returning an out-parameter usually also return a return code, and then an out parameter may or may not be written, which conditionally depends on the exit code, e.g.:</p>
640*e5dd7070Spatrick
641*e5dd7070Spatrick<pre class="code_example">
642*e5dd7070Spatrickbool maybeCreateObject(LIBKERN_RETURNS_RETAINED OSObject **obj);
643*e5dd7070Spatrick</pre>
644*e5dd7070Spatrick
645*e5dd7070Spatrick<p>For such functions, the usual semantics is that an object is written into on "success", and not written into on "failure".<p>
646*e5dd7070Spatrick
647*e5dd7070Spatrick<p>For <tt>LIBKERN_RETURNS_RETAINED</tt> we assume the following definition of
648*e5dd7070Spatricksuccess:</p>
649*e5dd7070Spatrick
650*e5dd7070Spatrick<p>For functions returning <tt>OSReturn</tt> or <tt>IOReturn</tt>
651*e5dd7070Spatrick(any typedef to <tt>kern_return_t</tt>) success is defined as having an output of zero (<tt>kIOReturnSuccess</tt> is zero).
652*e5dd7070SpatrickFor all others, success is non-zero (e.g. non-nullptr for pointers)</p>
653*e5dd7070Spatrick
654*e5dd7070Spatrick<p><b>3. Retained out parameters on zero return</b>
655*e5dd7070SpatrickThe annotation <tt>LIBKERN_RETURNS_RETAINED_ON_ZERO</tt> states
656*e5dd7070Spatrickthat a retained object is written into if and only if the function returns a zero value:</p>
657*e5dd7070Spatrick
658*e5dd7070Spatrick<pre class="code_example">
659*e5dd7070Spatrickbool OSUnserializeXML(void *data, LIBKERN_RETURNS_RETAINED_ON_ZERO OSString **errString);
660*e5dd7070Spatrick</pre>
661*e5dd7070Spatrick
662*e5dd7070Spatrick<p>Then the caller has to release an object if the function has returned zero.</p>
663*e5dd7070Spatrick
664*e5dd7070Spatrick<p><b>4. Retained out parameters on non-zero return</b>
665*e5dd7070SpatrickSimilarly, <tt>LIBKERN_RETURNS_RETAINED_ON_NONZERO</tt> specifies that a
666*e5dd7070Spatrickretained object is written into the parameter if and only if the function has
667*e5dd7070Spatrickreturned a non-zero value.</p>
668*e5dd7070Spatrick
669*e5dd7070Spatrick<p>Note that for non-retained out parameters conditionals do not matter, as the
670*e5dd7070Spatrickcaller has no obligations regardless of whether an object is written into or
671*e5dd7070Spatricknot.</p>
672*e5dd7070Spatrick
673*e5dd7070Spatrick<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
674*e5dd7070Spatrick<h2 id="custom_assertions">Custom Assertion Handlers</h2>
675*e5dd7070Spatrick<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
676*e5dd7070Spatrick
677*e5dd7070Spatrick<p>The analyzer exploits code assertions by pruning off paths where the
678*e5dd7070Spatrickassertion condition is false. The idea is capture any program invariants
679*e5dd7070Spatrickspecified in the assertion that the developer may know but is not immediately
680*e5dd7070Spatrickapparent in the code itself. In this way assertions make implicit assumptions
681*e5dd7070Spatrickexplicit in the code, which not only makes the analyzer more accurate when
682*e5dd7070Spatrickfinding bugs, but can help others better able to understand your code as well.
683*e5dd7070SpatrickIt can also help remove certain kinds of analyzer false positives by pruning off
684*e5dd7070Spatrickfalse paths.</p>
685*e5dd7070Spatrick
686*e5dd7070Spatrick<p>In order to exploit assertions, however, the analyzer must understand when it
687*e5dd7070Spatrickencounters an &quot;assertion handler.&quot; Typically assertions are
688*e5dd7070Spatrickimplemented with a macro, with the macro performing a check for the assertion
689*e5dd7070Spatrickcondition and, when the check fails, calling an assertion handler.  For example, consider the following code
690*e5dd7070Spatrickfragment:</p>
691*e5dd7070Spatrick
692*e5dd7070Spatrick<pre class="code_example">
693*e5dd7070Spatrickvoid foo(int *p) {
694*e5dd7070Spatrick  assert(p != NULL);
695*e5dd7070Spatrick}
696*e5dd7070Spatrick</pre>
697*e5dd7070Spatrick
698*e5dd7070Spatrick<p>When this code is preprocessed on Mac OS X it expands to the following:</p>
699*e5dd7070Spatrick
700*e5dd7070Spatrick<pre class="code_example">
701*e5dd7070Spatrickvoid foo(int *p) {
702*e5dd7070Spatrick  (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
703*e5dd7070Spatrick}
704*e5dd7070Spatrick</pre>
705*e5dd7070Spatrick
706*e5dd7070Spatrick<p>In this example, the assertion handler is <tt>__assert_rtn</tt>. When called,
707*e5dd7070Spatrickmost assertion handlers typically print an error and terminate the program. The
708*e5dd7070Spatrickanalyzer can exploit such semantics by ending the analysis of a path once it
709*e5dd7070Spatrickhits a call to an assertion handler.</p>
710*e5dd7070Spatrick
711*e5dd7070Spatrick<p>The trick, however, is that the analyzer needs to know that a called function
712*e5dd7070Spatrickis an assertion handler; otherwise the analyzer might assume the function call
713*e5dd7070Spatrickreturns and it will continue analyzing the path where the assertion condition
714*e5dd7070Spatrickfailed. This can lead to false positives, as the assertion condition usually
715*e5dd7070Spatrickimplies a safety condition (e.g., a pointer is not null) prior to performing
716*e5dd7070Spatricksome action that depends on that condition (e.g., dereferencing a pointer).</p>
717*e5dd7070Spatrick
718*e5dd7070Spatrick<p>The analyzer knows about several well-known assertion handlers, but can
719*e5dd7070Spatrickautomatically infer if a function should be treated as an assertion handler if
720*e5dd7070Spatrickit is annotated with the 'noreturn' attribute or the (Clang-specific)
721*e5dd7070Spatrick'analyzer_noreturn' attribute. Note that, currently, clang does not support
722*e5dd7070Spatrickthese attributes on Objective-C methods and C++ methods.</p>
723*e5dd7070Spatrick
724*e5dd7070Spatrick<h4 id="attr_noreturn">Attribute 'noreturn'</h4>
725*e5dd7070Spatrick
726*e5dd7070Spatrick<p>The 'noreturn' attribute is a GCC-attribute that can be placed on the
727*e5dd7070Spatrickdeclarations of functions. It means exactly what its name implies: a function
728*e5dd7070Spatrickwith a 'noreturn' attribute should never return.</p>
729*e5dd7070Spatrick
730*e5dd7070Spatrick<p>Specific details of the syntax of using the 'noreturn' attribute can be found
731*e5dd7070Spatrickin <a
732*e5dd7070Spatrickhref="https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute">GCC's
733*e5dd7070Spatrickdocumentation</a>.</p>
734*e5dd7070Spatrick
735*e5dd7070Spatrick<p>Not only does the analyzer exploit this information when pruning false paths,
736*e5dd7070Spatrickbut the compiler also takes it seriously and will generate different code (and
737*e5dd7070Spatrickpossibly better optimized) under the assumption that the function does not
738*e5dd7070Spatrickreturn.</p>
739*e5dd7070Spatrick
740*e5dd7070Spatrick<p><b>Example</b></p>
741*e5dd7070Spatrick
742*e5dd7070Spatrick<p>On Mac OS X, the function prototype for <tt>__assert_rtn</tt> (declared in
743*e5dd7070Spatrick<tt>assert.h</tt>) is specifically annotated with the 'noreturn' attribute:</p>
744*e5dd7070Spatrick
745*e5dd7070Spatrick<pre class="code_example">
746*e5dd7070Spatrickvoid __assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">__attribute__((__noreturn__))</span>;
747*e5dd7070Spatrick</pre>
748*e5dd7070Spatrick
749*e5dd7070Spatrick<h4 id="attr_analyzer_noreturn">Attribute 'analyzer_noreturn' (Clang-specific)</h4>
750*e5dd7070Spatrick
751*e5dd7070Spatrick<p>The Clang-specific 'analyzer_noreturn' attribute is almost identical to
752*e5dd7070Spatrick'noreturn' except that it is ignored by the compiler for the purposes of code
753*e5dd7070Spatrickgeneration.</p>
754*e5dd7070Spatrick
755*e5dd7070Spatrick<p>This attribute is useful for annotating assertion handlers that actually
756*e5dd7070Spatrick<em>can</em> return, but for the purpose of using the analyzer we want to
757*e5dd7070Spatrickpretend that such functions do not return.</p>
758*e5dd7070Spatrick
759*e5dd7070Spatrick<p>Because this attribute is Clang-specific, its use should be conditioned with
760*e5dd7070Spatrickthe use of preprocessor macros.</p>
761*e5dd7070Spatrick
762*e5dd7070Spatrick<p><b>Example</b>
763*e5dd7070Spatrick
764*e5dd7070Spatrick<pre class="code_example">
765*e5dd7070Spatrick#ifndef CLANG_ANALYZER_NORETURN
766*e5dd7070Spatrick#if __has_feature(attribute_analyzer_noreturn)
767*e5dd7070Spatrick<span class="code_highlight">#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))</span>
768*e5dd7070Spatrick#else
769*e5dd7070Spatrick#define CLANG_ANALYZER_NORETURN
770*e5dd7070Spatrick#endif
771*e5dd7070Spatrick#endif
772*e5dd7070Spatrick
773*e5dd7070Spatrickvoid my_assert_rtn(const char *, const char *, int, const char *) <span class="code_highlight">CLANG_ANALYZER_NORETURN</span>;
774*e5dd7070Spatrick</pre>
775*e5dd7070Spatrick
776*e5dd7070Spatrick</div>
777*e5dd7070Spatrick</div>
778*e5dd7070Spatrick</body>
779*e5dd7070Spatrick</html>
780