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 "standard" 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 & 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 & 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 "alloc" or "new" or contains the word 158*e5dd7070Spatrick"copy".</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 <Foundation/Foundation.h> 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 "owning" 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 "create" or "copy". 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 <Cocoa/Cocoa.h> 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"owning" 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"consumed" (a single reference count decremented) after the message 460*e5dd7070Spatrickis sent. This matches the semantics of all "init" 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 "assertion handler." 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