1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s 2*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s 3*67e74705SXin Li 4*67e74705SXin Li#include "Inputs/system-header-simulator-for-objc-dealloc.h" 5*67e74705SXin Li 6*67e74705SXin Li#define NON_ARC !__has_feature(objc_arc) 7*67e74705SXin Li 8*67e74705SXin Li#if NON_ARC 9*67e74705SXin Li#define WEAK_ON_ARC 10*67e74705SXin Li#else 11*67e74705SXin Li#define WEAK_ON_ARC __weak 12*67e74705SXin Li#endif 13*67e74705SXin Li 14*67e74705SXin Li// No diagnostics expected under ARC. 15*67e74705SXin Li#if !NON_ARC 16*67e74705SXin Li // expected-no-diagnostics 17*67e74705SXin Li#endif 18*67e74705SXin Li 19*67e74705SXin Li// Do not warn about missing release in -dealloc for ivars. 20*67e74705SXin Li 21*67e74705SXin Li@interface MyIvarClass1 : NSObject { 22*67e74705SXin Li NSObject *_ivar; 23*67e74705SXin Li} 24*67e74705SXin Li@end 25*67e74705SXin Li 26*67e74705SXin Li@implementation MyIvarClass1 27*67e74705SXin Li- (instancetype)initWithIvar:(NSObject *)ivar 28*67e74705SXin Li{ 29*67e74705SXin Li self = [super init]; 30*67e74705SXin Li if (!self) 31*67e74705SXin Li return nil; 32*67e74705SXin Li#if NON_ARC 33*67e74705SXin Li _ivar = [ivar retain]; 34*67e74705SXin Li#endif 35*67e74705SXin Li return self; 36*67e74705SXin Li} 37*67e74705SXin Li- (void)dealloc 38*67e74705SXin Li{ 39*67e74705SXin Li#if NON_ARC 40*67e74705SXin Li [super dealloc]; 41*67e74705SXin Li#endif 42*67e74705SXin Li} 43*67e74705SXin Li@end 44*67e74705SXin Li 45*67e74705SXin Li@interface MyIvarClass2 : NSObject { 46*67e74705SXin Li NSObject *_ivar; 47*67e74705SXin Li} 48*67e74705SXin Li- (NSObject *)ivar; 49*67e74705SXin Li- (void)setIvar:(NSObject *)ivar; 50*67e74705SXin Li@end 51*67e74705SXin Li 52*67e74705SXin Li@implementation MyIvarClass2 53*67e74705SXin Li- (instancetype)init 54*67e74705SXin Li{ 55*67e74705SXin Li self = [super init]; 56*67e74705SXin Li return self; 57*67e74705SXin Li} 58*67e74705SXin Li- (void)dealloc 59*67e74705SXin Li{ 60*67e74705SXin Li#if NON_ARC 61*67e74705SXin Li [super dealloc]; 62*67e74705SXin Li#endif 63*67e74705SXin Li} 64*67e74705SXin Li- (NSObject *)ivar 65*67e74705SXin Li{ 66*67e74705SXin Li return _ivar; 67*67e74705SXin Li} 68*67e74705SXin Li- (void)setIvar:(NSObject *)ivar 69*67e74705SXin Li{ 70*67e74705SXin Li#if NON_ARC 71*67e74705SXin Li [_ivar release]; 72*67e74705SXin Li _ivar = [ivar retain]; 73*67e74705SXin Li#else 74*67e74705SXin Li _ivar = ivar; 75*67e74705SXin Li#endif 76*67e74705SXin Li} 77*67e74705SXin Li@end 78*67e74705SXin Li 79*67e74705SXin Li// Warn about missing release in -dealloc for properties. 80*67e74705SXin Li 81*67e74705SXin Li@interface MyPropertyClass1 : NSObject 82*67e74705SXin Li@property (copy) NSObject *ivar; 83*67e74705SXin Li@end 84*67e74705SXin Li 85*67e74705SXin Li@implementation MyPropertyClass1 86*67e74705SXin Li- (void)dealloc 87*67e74705SXin Li{ 88*67e74705SXin Li#if NON_ARC 89*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass1' was copied by a synthesized property but not released before '[super dealloc]'}} 90*67e74705SXin Li#endif 91*67e74705SXin Li} 92*67e74705SXin Li@end 93*67e74705SXin Li 94*67e74705SXin Li@interface MyPropertyClass2 : NSObject 95*67e74705SXin Li@property (retain) NSObject *ivar; 96*67e74705SXin Li@end 97*67e74705SXin Li 98*67e74705SXin Li@implementation MyPropertyClass2 99*67e74705SXin Li- (void)dealloc 100*67e74705SXin Li{ 101*67e74705SXin Li#if NON_ARC 102*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass2' was retained by a synthesized property but not released before '[super dealloc]'}} 103*67e74705SXin Li#endif 104*67e74705SXin Li} 105*67e74705SXin Li@end 106*67e74705SXin Li 107*67e74705SXin Li@interface MyPropertyClass3 : NSObject { 108*67e74705SXin Li NSObject *_ivar; 109*67e74705SXin Li} 110*67e74705SXin Li@property (retain) NSObject *ivar; 111*67e74705SXin Li@end 112*67e74705SXin Li 113*67e74705SXin Li@implementation MyPropertyClass3 114*67e74705SXin Li@synthesize ivar = _ivar; 115*67e74705SXin Li- (void)dealloc 116*67e74705SXin Li{ 117*67e74705SXin Li#if NON_ARC 118*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass3' was retained by a synthesized property but not released before '[super dealloc]'}} 119*67e74705SXin Li#endif 120*67e74705SXin Li} 121*67e74705SXin Li 122*67e74705SXin Li@end 123*67e74705SXin Li 124*67e74705SXin Li@interface MyPropertyClass4 : NSObject { 125*67e74705SXin Li void (^_blockPropertyIvar)(void); 126*67e74705SXin Li} 127*67e74705SXin Li@property (copy) void (^blockProperty)(void); 128*67e74705SXin Li@property (copy) void (^blockProperty2)(void); 129*67e74705SXin Li@property (copy) void (^blockProperty3)(void); 130*67e74705SXin Li 131*67e74705SXin Li@end 132*67e74705SXin Li 133*67e74705SXin Li@implementation MyPropertyClass4 134*67e74705SXin Li@synthesize blockProperty = _blockPropertyIvar; 135*67e74705SXin Li- (void)dealloc 136*67e74705SXin Li{ 137*67e74705SXin Li#if NON_ARC 138*67e74705SXin Li [_blockProperty2 release]; 139*67e74705SXin Li Block_release(_blockProperty3); 140*67e74705SXin Li 141*67e74705SXin Li [super dealloc]; // expected-warning {{The '_blockPropertyIvar' ivar in 'MyPropertyClass4' was copied by a synthesized property but not released before '[super dealloc]'}} 142*67e74705SXin Li#endif 143*67e74705SXin Li} 144*67e74705SXin Li@end 145*67e74705SXin Li 146*67e74705SXin Li@interface MyPropertyClass5 : NSObject { 147*67e74705SXin Li WEAK_ON_ARC NSObject *_ivar; 148*67e74705SXin Li} 149*67e74705SXin Li@property (weak) NSObject *ivar; 150*67e74705SXin Li@end 151*67e74705SXin Li 152*67e74705SXin Li@implementation MyPropertyClass5 153*67e74705SXin Li@synthesize ivar = _ivar; 154*67e74705SXin Li- (void)dealloc 155*67e74705SXin Li{ 156*67e74705SXin Li#if NON_ARC 157*67e74705SXin Li [super dealloc]; // no-warning because it is a weak property 158*67e74705SXin Li#endif 159*67e74705SXin Li} 160*67e74705SXin Li@end 161*67e74705SXin Li 162*67e74705SXin Li@interface MyPropertyClassWithReturnInDealloc : NSObject { 163*67e74705SXin Li NSObject *_ivar; 164*67e74705SXin Li} 165*67e74705SXin Li@property (retain) NSObject *ivar; 166*67e74705SXin Li@end 167*67e74705SXin Li 168*67e74705SXin Li@implementation MyPropertyClassWithReturnInDealloc 169*67e74705SXin Li@synthesize ivar = _ivar; 170*67e74705SXin Li- (void)dealloc 171*67e74705SXin Li{ 172*67e74705SXin Li return; 173*67e74705SXin Li#if NON_ARC 174*67e74705SXin Li // expected-warning@-2{{The '_ivar' ivar in 'MyPropertyClassWithReturnInDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} 175*67e74705SXin Li [super dealloc]; 176*67e74705SXin Li#endif 177*67e74705SXin Li} 178*67e74705SXin Li@end 179*67e74705SXin Li 180*67e74705SXin Li@interface MyPropertyClassWithReleaseInOtherInstance : NSObject { 181*67e74705SXin Li NSObject *_ivar; 182*67e74705SXin Li MyPropertyClassWithReleaseInOtherInstance *_other; 183*67e74705SXin Li} 184*67e74705SXin Li@property (retain) NSObject *ivar; 185*67e74705SXin Li 186*67e74705SXin Li-(void)releaseIvars; 187*67e74705SXin Li@end 188*67e74705SXin Li 189*67e74705SXin Li@implementation MyPropertyClassWithReleaseInOtherInstance 190*67e74705SXin Li@synthesize ivar = _ivar; 191*67e74705SXin Li 192*67e74705SXin Li-(void)releaseIvars; { 193*67e74705SXin Li#if NON_ARC 194*67e74705SXin Li [_ivar release]; 195*67e74705SXin Li#endif 196*67e74705SXin Li} 197*67e74705SXin Li 198*67e74705SXin Li- (void)dealloc 199*67e74705SXin Li{ 200*67e74705SXin Li [_other releaseIvars]; 201*67e74705SXin Li#if NON_ARC 202*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClassWithReleaseInOtherInstance' was retained by a synthesized property but not released before '[super dealloc]'}} 203*67e74705SXin Li#endif 204*67e74705SXin Li} 205*67e74705SXin Li@end 206*67e74705SXin Li 207*67e74705SXin Li@interface MyPropertyClassWithNeitherReturnNorSuperDealloc : NSObject { 208*67e74705SXin Li NSObject *_ivar; 209*67e74705SXin Li} 210*67e74705SXin Li@property (retain) NSObject *ivar; 211*67e74705SXin Li@end 212*67e74705SXin Li 213*67e74705SXin Li@implementation MyPropertyClassWithNeitherReturnNorSuperDealloc 214*67e74705SXin Li@synthesize ivar = _ivar; 215*67e74705SXin Li- (void)dealloc 216*67e74705SXin Li{ 217*67e74705SXin Li} 218*67e74705SXin Li#if NON_ARC 219*67e74705SXin Li // expected-warning@-2 {{method possibly missing a [super dealloc] call}} (From Sema) 220*67e74705SXin Li // expected-warning@-3{{The '_ivar' ivar in 'MyPropertyClassWithNeitherReturnNorSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} 221*67e74705SXin Li#endif 222*67e74705SXin Li@end 223*67e74705SXin Li 224*67e74705SXin Li// <rdar://problem/6380411>: 'myproperty' has kind 'assign' and thus the 225*67e74705SXin Li// assignment through the setter does not perform a release. 226*67e74705SXin Li 227*67e74705SXin Li@interface MyObject : NSObject { 228*67e74705SXin Li id __unsafe_unretained _myproperty; 229*67e74705SXin Li} 230*67e74705SXin Li@property(assign) id myproperty; 231*67e74705SXin Li@end 232*67e74705SXin Li 233*67e74705SXin Li@implementation MyObject 234*67e74705SXin Li@synthesize myproperty=_myproperty; // no-warning 235*67e74705SXin Li- (void)dealloc { 236*67e74705SXin Li // Don't claim that myproperty is released since it the property 237*67e74705SXin Li // has the 'assign' attribute. 238*67e74705SXin Li self.myproperty = 0; // no-warning 239*67e74705SXin Li#if NON_ARC 240*67e74705SXin Li [super dealloc]; 241*67e74705SXin Li#endif 242*67e74705SXin Li} 243*67e74705SXin Li@end 244*67e74705SXin Li 245*67e74705SXin Li@interface ClassWithControlFlowInRelease : NSObject { 246*67e74705SXin Li BOOL _ivar1; 247*67e74705SXin Li} 248*67e74705SXin Li@property (retain) NSObject *ivar2; 249*67e74705SXin Li@end 250*67e74705SXin Li 251*67e74705SXin Li@implementation ClassWithControlFlowInRelease 252*67e74705SXin Li- (void)dealloc; { 253*67e74705SXin Li if (_ivar1) { 254*67e74705SXin Li // We really should warn because there is a path through -dealloc on which 255*67e74705SXin Li // _ivar2 is not released. 256*67e74705SXin Li#if NON_ARC 257*67e74705SXin Li [_ivar2 release]; 258*67e74705SXin Li#endif 259*67e74705SXin Li } 260*67e74705SXin Li 261*67e74705SXin Li#if NON_ARC 262*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar2' ivar in 'ClassWithControlFlowInRelease' was retained by a synthesized property but not released before '[super dealloc]'}} 263*67e74705SXin Li#endif 264*67e74705SXin Li} 265*67e74705SXin Li@end 266*67e74705SXin Li 267*67e74705SXin Li// Don't warn when the property is nil'd out in -dealloc 268*67e74705SXin Li 269*67e74705SXin Li@interface ClassWithNildOutProperty : NSObject 270*67e74705SXin Li@property (retain) NSObject *ivar; 271*67e74705SXin Li@property (assign) int *intPtrProp; 272*67e74705SXin Li@end 273*67e74705SXin Li 274*67e74705SXin Li@implementation ClassWithNildOutProperty 275*67e74705SXin Li- (void)dealloc; { 276*67e74705SXin Li self.ivar = nil; 277*67e74705SXin Li 278*67e74705SXin Li // Make sure to handle setting a non-retainable property to 0. 279*67e74705SXin Li self.intPtrProp = 0; 280*67e74705SXin Li#if NON_ARC 281*67e74705SXin Li [super dealloc]; // no-warning 282*67e74705SXin Li#endif 283*67e74705SXin Li} 284*67e74705SXin Li@end 285*67e74705SXin Li 286*67e74705SXin Li// Do warn when the ivar but not the property is nil'd out in -dealloc 287*67e74705SXin Li 288*67e74705SXin Li@interface ClassWithNildOutIvar : NSObject 289*67e74705SXin Li@property (retain) NSObject *ivar; 290*67e74705SXin Li@end 291*67e74705SXin Li 292*67e74705SXin Li@implementation ClassWithNildOutIvar 293*67e74705SXin Li- (void)dealloc; { 294*67e74705SXin Li // Oops. Meant self.ivar = nil 295*67e74705SXin Li _ivar = nil; 296*67e74705SXin Li 297*67e74705SXin Li#if NON_ARC 298*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWithNildOutIvar' was retained by a synthesized property but not released before '[super dealloc]'}} 299*67e74705SXin Li#endif 300*67e74705SXin Li} 301*67e74705SXin Li@end 302*67e74705SXin Li 303*67e74705SXin Li// Do warn when the ivar is updated to a different value that is then 304*67e74705SXin Li// released. 305*67e74705SXin Li 306*67e74705SXin Li@interface ClassWithUpdatedIvar : NSObject 307*67e74705SXin Li@property (retain) NSObject *ivar; 308*67e74705SXin Li@end 309*67e74705SXin Li 310*67e74705SXin Li@implementation ClassWithUpdatedIvar 311*67e74705SXin Li- (void)dealloc; { 312*67e74705SXin Li _ivar = [[NSObject alloc] init]; 313*67e74705SXin Li 314*67e74705SXin Li#if NON_ARC 315*67e74705SXin Li [_ivar release]; 316*67e74705SXin Li#endif 317*67e74705SXin Li 318*67e74705SXin Li#if NON_ARC 319*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWithUpdatedIvar' was retained by a synthesized property but not released before '[super dealloc]'}} 320*67e74705SXin Li#endif 321*67e74705SXin Li} 322*67e74705SXin Li@end 323*67e74705SXin Li 324*67e74705SXin Li 325*67e74705SXin Li// Don't warn when the property is nil'd out with a setter in -dealloc 326*67e74705SXin Li 327*67e74705SXin Li@interface ClassWithNildOutPropertyViaSetter : NSObject 328*67e74705SXin Li@property (retain) NSObject *ivar; 329*67e74705SXin Li@end 330*67e74705SXin Li 331*67e74705SXin Li@implementation ClassWithNildOutPropertyViaSetter 332*67e74705SXin Li- (void)dealloc; { 333*67e74705SXin Li [self setIvar:nil]; 334*67e74705SXin Li 335*67e74705SXin Li#if NON_ARC 336*67e74705SXin Li [super dealloc]; // no-warning 337*67e74705SXin Li#endif 338*67e74705SXin Li} 339*67e74705SXin Li@end 340*67e74705SXin Li 341*67e74705SXin Li 342*67e74705SXin Li// Don't warn about missing releases when -dealloc helpers are called. 343*67e74705SXin Li 344*67e74705SXin Li@interface ClassWithDeallocHelpers : NSObject 345*67e74705SXin Li@property (retain) NSObject *ivarReleasedInMethod; 346*67e74705SXin Li@property (retain) NSObject *propNilledOutInMethod; 347*67e74705SXin Li 348*67e74705SXin Li@property (retain) NSObject *ivarReleasedInFunction; 349*67e74705SXin Li@property (retain) NSObject *propNilledOutInFunction; 350*67e74705SXin Li 351*67e74705SXin Li@property (retain) NSObject *ivarNeverReleased; 352*67e74705SXin Li- (void)invalidateInMethod; 353*67e74705SXin Li@end 354*67e74705SXin Li 355*67e74705SXin Livoid ReleaseValueHelper(NSObject *iv) { 356*67e74705SXin Li#if NON_ARC 357*67e74705SXin Li [iv release]; 358*67e74705SXin Li#endif 359*67e74705SXin Li} 360*67e74705SXin Li 361*67e74705SXin Livoid NilOutPropertyHelper(ClassWithDeallocHelpers *o) { 362*67e74705SXin Li o.propNilledOutInFunction = nil; 363*67e74705SXin Li} 364*67e74705SXin Li 365*67e74705SXin Li@implementation ClassWithDeallocHelpers 366*67e74705SXin Li- (void)invalidateInMethod { 367*67e74705SXin Li#if NON_ARC 368*67e74705SXin Li [_ivarReleasedInMethod release]; 369*67e74705SXin Li#endif 370*67e74705SXin Li self.propNilledOutInMethod = nil; 371*67e74705SXin Li} 372*67e74705SXin Li 373*67e74705SXin Li- (void)dealloc; { 374*67e74705SXin Li ReleaseValueHelper(_ivarReleasedInFunction); 375*67e74705SXin Li NilOutPropertyHelper(self); 376*67e74705SXin Li 377*67e74705SXin Li [self invalidateInMethod]; 378*67e74705SXin Li#if NON_ARC 379*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivarNeverReleased' ivar in 'ClassWithDeallocHelpers' was retained by a synthesized property but not released before '[super dealloc]'}} 380*67e74705SXin Li#endif 381*67e74705SXin Li} 382*67e74705SXin Li@end 383*67e74705SXin Li 384*67e74705SXin Li 385*67e74705SXin Li// Don't warn when self in -dealloc escapes. 386*67e74705SXin Li 387*67e74705SXin Li@interface ClassWhereSelfEscapesViaMethodCall : NSObject 388*67e74705SXin Li@property (retain) NSObject *ivar; // no-warning 389*67e74705SXin Li@end 390*67e74705SXin Li 391*67e74705SXin Li@interface ClassWhereSelfEscapesViaMethodCall (Other) 392*67e74705SXin Li- (void)invalidate; // In other translation unit. 393*67e74705SXin Li@end 394*67e74705SXin Li 395*67e74705SXin Li@implementation ClassWhereSelfEscapesViaMethodCall 396*67e74705SXin Li- (void)dealloc; { 397*67e74705SXin Li [self invalidate]; 398*67e74705SXin Li#if NON_ARC 399*67e74705SXin Li [super dealloc]; 400*67e74705SXin Li#endif 401*67e74705SXin Li} // no-warning 402*67e74705SXin Li@end 403*67e74705SXin Li 404*67e74705SXin Li@interface ClassWhereSelfEscapesViaPropertyAccess : NSObject 405*67e74705SXin Li@property (retain) NSObject *ivar; 406*67e74705SXin Li@end 407*67e74705SXin Li 408*67e74705SXin Li@interface ClassWhereSelfEscapesViaPropertyAccess (Other) 409*67e74705SXin Li// The implementation of this property is unknown and therefore could 410*67e74705SXin Li// release ivar. 411*67e74705SXin Li@property (retain) NSObject *otherIvar; 412*67e74705SXin Li@end 413*67e74705SXin Li 414*67e74705SXin Li@implementation ClassWhereSelfEscapesViaPropertyAccess 415*67e74705SXin Li- (void)dealloc; { 416*67e74705SXin Li self.otherIvar = nil; 417*67e74705SXin Li#if NON_ARC 418*67e74705SXin Li [super dealloc]; 419*67e74705SXin Li#endif 420*67e74705SXin Li} // no-warning 421*67e74705SXin Li@end 422*67e74705SXin Li 423*67e74705SXin Li// Don't treat self as escaping when setter called on *synthesized* 424*67e74705SXin Li// property. 425*67e74705SXin Li 426*67e74705SXin Li@interface ClassWhereSelfEscapesViaSynthesizedPropertyAccess : NSObject 427*67e74705SXin Li@property (retain) NSObject *ivar; 428*67e74705SXin Li@property (retain) NSObject *otherIvar; 429*67e74705SXin Li@end 430*67e74705SXin Li 431*67e74705SXin Li@implementation ClassWhereSelfEscapesViaSynthesizedPropertyAccess 432*67e74705SXin Li- (void)dealloc; { 433*67e74705SXin Li self.otherIvar = nil; 434*67e74705SXin Li#if NON_ARC 435*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWhereSelfEscapesViaSynthesizedPropertyAccess' was retained by a synthesized property but not released before '[super dealloc]'}} 436*67e74705SXin Li#endif 437*67e74705SXin Li} 438*67e74705SXin Li@end 439*67e74705SXin Li 440*67e74705SXin Li 441*67e74705SXin Li// Don't treat calls to system headers as escapes 442*67e74705SXin Li 443*67e74705SXin Li@interface ClassWhereSelfEscapesViaCallToSystem : NSObject 444*67e74705SXin Li@property (retain) NSObject *ivar1; 445*67e74705SXin Li@property (retain) NSObject *ivar2; 446*67e74705SXin Li@property (retain) NSObject *ivar3; 447*67e74705SXin Li@property (retain) NSObject *ivar4; 448*67e74705SXin Li@property (retain) NSObject *ivar5; 449*67e74705SXin Li@property (retain) NSObject *ivar6; 450*67e74705SXin Li@end 451*67e74705SXin Li 452*67e74705SXin Li@implementation ClassWhereSelfEscapesViaCallToSystem 453*67e74705SXin Li- (void)dealloc; { 454*67e74705SXin Li#if NON_ARC 455*67e74705SXin Li [_ivar2 release]; 456*67e74705SXin Li if (_ivar3) { 457*67e74705SXin Li [_ivar3 release]; 458*67e74705SXin Li } 459*67e74705SXin Li#endif 460*67e74705SXin Li 461*67e74705SXin Li [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self]; 462*67e74705SXin Li [[NSNotificationCenter defaultCenter] removeObserver:self]; 463*67e74705SXin Li 464*67e74705SXin Li#if NON_ARC 465*67e74705SXin Li [_ivar4 release]; 466*67e74705SXin Li 467*67e74705SXin Li if (_ivar5) { 468*67e74705SXin Li [_ivar5 release]; 469*67e74705SXin Li } 470*67e74705SXin Li#endif 471*67e74705SXin Li 472*67e74705SXin Li [[NSNotificationCenter defaultCenter] removeObserver:self]; 473*67e74705SXin Li 474*67e74705SXin Li#if NON_ARC 475*67e74705SXin Li if (_ivar6) { 476*67e74705SXin Li [_ivar6 release]; 477*67e74705SXin Li } 478*67e74705SXin Li 479*67e74705SXin Li [super dealloc]; // expected-warning {{The '_ivar1' ivar in 'ClassWhereSelfEscapesViaCallToSystem' was retained by a synthesized property but not released before '[super dealloc]'}} 480*67e74705SXin Li#endif 481*67e74705SXin Li} 482*67e74705SXin Li@end 483*67e74705SXin Li 484*67e74705SXin Li// Don't warn when value escapes. 485*67e74705SXin Li 486*67e74705SXin Li@interface ClassWhereIvarValueEscapes : NSObject 487*67e74705SXin Li@property (retain) NSObject *ivar; 488*67e74705SXin Li@end 489*67e74705SXin Li 490*67e74705SXin Livoid ReleaseMe(id arg); 491*67e74705SXin Li 492*67e74705SXin Li@implementation ClassWhereIvarValueEscapes 493*67e74705SXin Li- (void)dealloc; { 494*67e74705SXin Li 495*67e74705SXin Li ReleaseMe(_ivar); 496*67e74705SXin Li 497*67e74705SXin Li#if NON_ARC 498*67e74705SXin Li [super dealloc]; 499*67e74705SXin Li#endif 500*67e74705SXin Li} // no-warning 501*67e74705SXin Li@end 502*67e74705SXin Li 503*67e74705SXin Li// Don't warn when value is known to be nil. 504*67e74705SXin Li 505*67e74705SXin Li@interface ClassWhereIvarIsNil : NSObject 506*67e74705SXin Li@property (retain) NSObject *ivarIsNil; 507*67e74705SXin Li@end 508*67e74705SXin Li 509*67e74705SXin Li@implementation ClassWhereIvarIsNil 510*67e74705SXin Li- (void)dealloc; { 511*67e74705SXin Li 512*67e74705SXin Li#if NON_ARC 513*67e74705SXin Li if (_ivarIsNil) 514*67e74705SXin Li [_ivarIsNil release]; 515*67e74705SXin Li 516*67e74705SXin Li [super dealloc]; 517*67e74705SXin Li#endif 518*67e74705SXin Li} // no-warning 519*67e74705SXin Li@end 520*67e74705SXin Li 521*67e74705SXin Li 522*67e74705SXin Li// Don't warn for non-retainable properties. 523*67e74705SXin Li 524*67e74705SXin Li@interface ClassWithNonRetainableProperty : NSObject 525*67e74705SXin Li@property (assign) int *ivar; // no-warning 526*67e74705SXin Li@end 527*67e74705SXin Li 528*67e74705SXin Li@implementation ClassWithNonRetainableProperty 529*67e74705SXin Li- (void)dealloc; { 530*67e74705SXin Li#if NON_ARC 531*67e74705SXin Li [super dealloc]; 532*67e74705SXin Li#endif 533*67e74705SXin Li} // no-warning 534*67e74705SXin Li@end 535*67e74705SXin Li 536*67e74705SXin Li 537*67e74705SXin Li@interface SuperClassOfClassWithInlinedSuperDealloc : NSObject 538*67e74705SXin Li@property (retain) NSObject *propInSuper; 539*67e74705SXin Li@end 540*67e74705SXin Li 541*67e74705SXin Li@implementation SuperClassOfClassWithInlinedSuperDealloc 542*67e74705SXin Li- (void)dealloc { 543*67e74705SXin Li#if NON_ARC 544*67e74705SXin Li [super dealloc]; // expected-warning {{The '_propInSuper' ivar in 'SuperClassOfClassWithInlinedSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} 545*67e74705SXin Li#endif 546*67e74705SXin Li} 547*67e74705SXin Li@end 548*67e74705SXin Li 549*67e74705SXin Li@interface ClassWithInlinedSuperDealloc : SuperClassOfClassWithInlinedSuperDealloc 550*67e74705SXin Li@property (retain) NSObject *propInSub; 551*67e74705SXin Li@end 552*67e74705SXin Li 553*67e74705SXin Li@implementation ClassWithInlinedSuperDealloc 554*67e74705SXin Li- (void)dealloc { 555*67e74705SXin Li#if NON_ARC 556*67e74705SXin Li [super dealloc]; // expected-warning {{The '_propInSub' ivar in 'ClassWithInlinedSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} 557*67e74705SXin Li#endif 558*67e74705SXin Li} 559*67e74705SXin Li@end 560*67e74705SXin Li 561*67e74705SXin Li 562*67e74705SXin Li@interface SuperClassOfClassWithInlinedSuperDeallocAndInvalidation : NSObject 563*67e74705SXin Li@property (retain) NSObject *propInSuper; 564*67e74705SXin Li 565*67e74705SXin Li- (void)invalidate; 566*67e74705SXin Li@end 567*67e74705SXin Li 568*67e74705SXin Li@implementation SuperClassOfClassWithInlinedSuperDeallocAndInvalidation 569*67e74705SXin Li 570*67e74705SXin Li- (void)invalidate { 571*67e74705SXin Li#if NON_ARC 572*67e74705SXin Li [_propInSuper release]; 573*67e74705SXin Li#endif 574*67e74705SXin Li _propInSuper = nil; 575*67e74705SXin Li} 576*67e74705SXin Li 577*67e74705SXin Li- (void)dealloc { 578*67e74705SXin Li [self invalidate]; 579*67e74705SXin Li#if NON_ARC 580*67e74705SXin Li [super dealloc]; // no-warning 581*67e74705SXin Li#endif 582*67e74705SXin Li} 583*67e74705SXin Li@end 584*67e74705SXin Li 585*67e74705SXin Li@interface ClassWithInlinedSuperDeallocAndInvalidation : SuperClassOfClassWithInlinedSuperDeallocAndInvalidation 586*67e74705SXin Li@property (retain) NSObject *propInSub; 587*67e74705SXin Li@end 588*67e74705SXin Li 589*67e74705SXin Li@implementation ClassWithInlinedSuperDeallocAndInvalidation 590*67e74705SXin Li 591*67e74705SXin Li- (void)invalidate { 592*67e74705SXin Li#if NON_ARC 593*67e74705SXin Li [_propInSub release]; 594*67e74705SXin Li#endif 595*67e74705SXin Li [super invalidate]; 596*67e74705SXin Li} 597*67e74705SXin Li 598*67e74705SXin Li- (void)dealloc { 599*67e74705SXin Li#if NON_ARC 600*67e74705SXin Li [super dealloc]; // no-warning 601*67e74705SXin Li#endif 602*67e74705SXin Li} 603*67e74705SXin Li@end 604*67e74705SXin Li 605*67e74705SXin Li 606*67e74705SXin Li@interface SuperClassOfClassThatEscapesBeforeInliningSuper : NSObject 607*67e74705SXin Li@property (retain) NSObject *propInSuper; 608*67e74705SXin Li@end 609*67e74705SXin Li 610*67e74705SXin Li@implementation SuperClassOfClassThatEscapesBeforeInliningSuper 611*67e74705SXin Li 612*67e74705SXin Li- (void)dealloc { 613*67e74705SXin Li 614*67e74705SXin Li#if NON_ARC 615*67e74705SXin Li [super dealloc]; // expected-warning {{The '_propInSuper' ivar in 'SuperClassOfClassThatEscapesBeforeInliningSuper' was retained by a synthesized property but not released before '[super dealloc]'}} 616*67e74705SXin Li#endif 617*67e74705SXin Li} 618*67e74705SXin Li@end 619*67e74705SXin Li 620*67e74705SXin Li@interface ClassThatEscapesBeforeInliningSuper : SuperClassOfClassThatEscapesBeforeInliningSuper 621*67e74705SXin Li@property (retain) NSObject *propInSub; 622*67e74705SXin Li@end 623*67e74705SXin Li 624*67e74705SXin Li@interface ClassThatEscapesBeforeInliningSuper (Other) 625*67e74705SXin Li- (void)invalidate; // No implementation in translation unit. 626*67e74705SXin Li@end 627*67e74705SXin Li 628*67e74705SXin Li@implementation ClassThatEscapesBeforeInliningSuper 629*67e74705SXin Li- (void)dealloc { 630*67e74705SXin Li [self invalidate]; 631*67e74705SXin Li 632*67e74705SXin Li#if NON_ARC 633*67e74705SXin Li [super dealloc]; // no-warning 634*67e74705SXin Li#endif 635*67e74705SXin Li} 636*67e74705SXin Li@end 637*67e74705SXin Li 638*67e74705SXin Li 639*67e74705SXin Li#if NON_ARC 640*67e74705SXin Li@interface ReleaseIvarInField : NSObject { 641*67e74705SXin Li int _tag; 642*67e74705SXin Li union { 643*67e74705SXin Li NSObject *field1; 644*67e74705SXin Li NSObject *field2; 645*67e74705SXin Li } _someUnion; 646*67e74705SXin Li 647*67e74705SXin Li struct { 648*67e74705SXin Li NSObject *field1; 649*67e74705SXin Li } _someStruct; 650*67e74705SXin Li} 651*67e74705SXin Li@end 652*67e74705SXin Li 653*67e74705SXin Li@implementation ReleaseIvarInField 654*67e74705SXin Li- (void)dealloc { 655*67e74705SXin Li if (_tag) { 656*67e74705SXin Li [_someUnion.field1 release]; 657*67e74705SXin Li } else { 658*67e74705SXin Li [_someUnion.field2 release]; 659*67e74705SXin Li } 660*67e74705SXin Li 661*67e74705SXin Li [_someStruct.field1 release]; 662*67e74705SXin Li [super dealloc]; 663*67e74705SXin Li} 664*67e74705SXin Li@end 665*67e74705SXin Li#endif 666*67e74705SXin Li 667*67e74705SXin Listruct SomeStruct { 668*67e74705SXin Li int f; 669*67e74705SXin Li}; 670*67e74705SXin Li@interface ZeroOutStructWithSetter : NSObject 671*67e74705SXin Li @property(assign) struct SomeStruct s; 672*67e74705SXin Li@end 673*67e74705SXin Li 674*67e74705SXin Li@implementation ZeroOutStructWithSetter 675*67e74705SXin Li- (void)dealloc { 676*67e74705SXin Li struct SomeStruct zeroedS; 677*67e74705SXin Li zeroedS.f = 0; 678*67e74705SXin Li 679*67e74705SXin Li self.s = zeroedS; 680*67e74705SXin Li#if NON_ARC 681*67e74705SXin Li [super dealloc]; 682*67e74705SXin Li#endif 683*67e74705SXin Li} 684*67e74705SXin Li@end 685*67e74705SXin Li 686*67e74705SXin Li#if NON_ARC 687*67e74705SXin Li@interface ReleaseIvarInArray : NSObject { 688*67e74705SXin Li NSObject *_array[3]; 689*67e74705SXin Li} 690*67e74705SXin Li@end 691*67e74705SXin Li 692*67e74705SXin Li@implementation ReleaseIvarInArray 693*67e74705SXin Li- (void)dealloc { 694*67e74705SXin Li for (int i = 0; i < 3; i++) { 695*67e74705SXin Li [_array[i] release]; 696*67e74705SXin Li } 697*67e74705SXin Li [super dealloc]; 698*67e74705SXin Li} 699*67e74705SXin Li@end 700*67e74705SXin Li#endif 701*67e74705SXin Li 702*67e74705SXin Li// Don't warn about missing releases for subclasses of SenTestCase or 703*67e74705SXin Li// for classes that are not subclasses of NSObject. 704*67e74705SXin Li 705*67e74705SXin Li@interface SenTestCase : NSObject {} 706*67e74705SXin Li@end 707*67e74705SXin Li 708*67e74705SXin Li@interface MyClassTest : SenTestCase 709*67e74705SXin Li@property (retain) NSObject *ivar; 710*67e74705SXin Li@end 711*67e74705SXin Li 712*67e74705SXin Li@implementation MyClassTest 713*67e74705SXin Li-(void)tearDown { 714*67e74705SXin Li#if NON_ARC 715*67e74705SXin Li [_ivar release]; 716*67e74705SXin Li#endif 717*67e74705SXin Li} 718*67e74705SXin Li 719*67e74705SXin Li-(void)dealloc; { 720*67e74705SXin Li#if NON_ARC 721*67e74705SXin Li [super dealloc]; // no-warning 722*67e74705SXin Li#endif 723*67e74705SXin Li} 724*67e74705SXin Li@end 725*67e74705SXin Li 726*67e74705SXin Li@interface XCTestCase : NSObject {} 727*67e74705SXin Li@end 728*67e74705SXin Li 729*67e74705SXin Li@interface MyClassXCTest : XCTestCase 730*67e74705SXin Li@property (retain) NSObject *ivar; 731*67e74705SXin Li@end 732*67e74705SXin Li 733*67e74705SXin Li@implementation MyClassXCTest 734*67e74705SXin Li-(void)tearDown { 735*67e74705SXin Li#if NON_ARC 736*67e74705SXin Li [_ivar release]; 737*67e74705SXin Li#endif 738*67e74705SXin Li} 739*67e74705SXin Li 740*67e74705SXin Li-(void)dealloc; { 741*67e74705SXin Li#if NON_ARC 742*67e74705SXin Li [super dealloc]; // no-warning 743*67e74705SXin Li#endif 744*67e74705SXin Li} 745*67e74705SXin Li@end 746*67e74705SXin Li 747*67e74705SXin Li 748*67e74705SXin Li__attribute__((objc_root_class)) 749*67e74705SXin Li@interface NonNSObjectMissingDealloc 750*67e74705SXin Li@property (retain) NSObject *ivar; 751*67e74705SXin Li@end 752*67e74705SXin Li@implementation NonNSObjectMissingDealloc 753*67e74705SXin Li-(void)dealloc; { 754*67e74705SXin Li 755*67e74705SXin Li} 756*67e74705SXin Li@end 757*67e74705SXin Li 758*67e74705SXin Li// Warn about calling -dealloc rather than release by mistake. 759*67e74705SXin Li 760*67e74705SXin Li@interface CallDeallocOnRetainPropIvar : NSObject { 761*67e74705SXin Li NSObject *okToDeallocDirectly; 762*67e74705SXin Li} 763*67e74705SXin Li 764*67e74705SXin Li@property (retain) NSObject *ivar; 765*67e74705SXin Li@end 766*67e74705SXin Li 767*67e74705SXin Li@implementation CallDeallocOnRetainPropIvar 768*67e74705SXin Li- (void)dealloc 769*67e74705SXin Li{ 770*67e74705SXin Li#if NON_ARC 771*67e74705SXin Li // Only warn for synthesized ivars. 772*67e74705SXin Li [okToDeallocDirectly dealloc]; // no-warning 773*67e74705SXin Li [_ivar dealloc]; // expected-warning {{'_ivar' should be released rather than deallocated}} 774*67e74705SXin Li 775*67e74705SXin Li [super dealloc]; 776*67e74705SXin Li#endif 777*67e74705SXin Li} 778*67e74705SXin Li@end 779*67e74705SXin Li 780*67e74705SXin Li// CIFilter special cases. 781*67e74705SXin Li// By design, -[CIFilter dealloc] releases (by calling -setValue: forKey: with 782*67e74705SXin Li// 'nil') all ivars (even in its *subclasses*) with names starting with 783*67e74705SXin Li// 'input' or that are backed by properties with names starting with 'input'. 784*67e74705SXin Li// The Dealloc checker needs to take particular care to not warn about missing 785*67e74705SXin Li// releases in this case -- if the user adds a release quiet the 786*67e74705SXin Li// warning it may result in an over release. 787*67e74705SXin Li 788*67e74705SXin Li@interface ImmediateSubCIFilter : CIFilter { 789*67e74705SXin Li NSObject *inputIvar; 790*67e74705SXin Li NSObject *nonInputIvar; 791*67e74705SXin Li NSObject *notPrefixedButBackingPrefixedProperty; 792*67e74705SXin Li NSObject *inputPrefixedButBackingNonPrefixedProperty; 793*67e74705SXin Li} 794*67e74705SXin Li 795*67e74705SXin Li@property(retain) NSObject *inputIvar; 796*67e74705SXin Li@property(retain) NSObject *nonInputIvar; 797*67e74705SXin Li@property(retain) NSObject *inputAutoSynthesizedIvar; 798*67e74705SXin Li@property(retain) NSObject *inputExplicitlySynthesizedToNonPrefixedIvar; 799*67e74705SXin Li@property(retain) NSObject *nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar; 800*67e74705SXin Li 801*67e74705SXin Li@end 802*67e74705SXin Li 803*67e74705SXin Li@implementation ImmediateSubCIFilter 804*67e74705SXin Li@synthesize inputIvar = inputIvar; 805*67e74705SXin Li@synthesize nonInputIvar = nonInputIvar; 806*67e74705SXin Li@synthesize inputExplicitlySynthesizedToNonPrefixedIvar = notPrefixedButBackingPrefixedProperty; 807*67e74705SXin Li@synthesize nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar = inputPrefixedButBackingNonPrefixedProperty; 808*67e74705SXin Li 809*67e74705SXin Li- (void)dealloc { 810*67e74705SXin Li#if NON_ARC 811*67e74705SXin Li // We don't want warnings here for: 812*67e74705SXin Li // inputIvar 813*67e74705SXin Li // inputAutoSynthesizedIvar 814*67e74705SXin Li // inputExplicitlySynthesizedToNonPrefixedIvar 815*67e74705SXin Li // inputPrefixedButBackingNonPrefixedProperty 816*67e74705SXin Li [super dealloc]; 817*67e74705SXin Li // expected-warning@-1 {{The 'nonInputIvar' ivar in 'ImmediateSubCIFilter' was retained by a synthesized property but not released before '[super dealloc]'}} 818*67e74705SXin Li#endif 819*67e74705SXin Li} 820*67e74705SXin Li@end 821*67e74705SXin Li 822*67e74705SXin Li@interface SubSubCIFilter : CIFilter { 823*67e74705SXin Li NSObject *inputIvarInSub; 824*67e74705SXin Li} 825*67e74705SXin Li 826*67e74705SXin Li@property(retain) NSObject *inputIvarInSub; 827*67e74705SXin Li@end 828*67e74705SXin Li 829*67e74705SXin Li@implementation SubSubCIFilter 830*67e74705SXin Li@synthesize inputIvarInSub = inputIvarInSub; 831*67e74705SXin Li 832*67e74705SXin Li- (void)dealloc { 833*67e74705SXin Li// Don't warn about inputIvarInSub. 834*67e74705SXin Li#if NON_ARC 835*67e74705SXin Li [super dealloc]; 836*67e74705SXin Li#endif 837*67e74705SXin Li} 838*67e74705SXin Li@end 839*67e74705SXin Li@interface OverreleasingCIFilter : CIFilter { 840*67e74705SXin Li NSObject *inputIvar; 841*67e74705SXin Li} 842*67e74705SXin Li 843*67e74705SXin Li@property(retain) NSObject *inputIvar; 844*67e74705SXin Li@end 845*67e74705SXin Li 846*67e74705SXin Li@implementation OverreleasingCIFilter 847*67e74705SXin Li@synthesize inputIvar = inputIvar; 848*67e74705SXin Li 849*67e74705SXin Li- (void)dealloc { 850*67e74705SXin Li#if NON_ARC 851*67e74705SXin Li // This is an over release because CIFilter's dealloc will also release it. 852*67e74705SXin Li [inputIvar release]; // expected-warning {{The 'inputIvar' ivar in 'OverreleasingCIFilter' will be released by '-[CIFilter dealloc]' but also released here}} 853*67e74705SXin Li [super dealloc]; // no-warning 854*67e74705SXin Li #endif 855*67e74705SXin Li} 856*67e74705SXin Li@end 857*67e74705SXin Li 858*67e74705SXin Li 859*67e74705SXin Li@interface NotMissingDeallocCIFilter : CIFilter { 860*67e74705SXin Li NSObject *inputIvar; 861*67e74705SXin Li} 862*67e74705SXin Li 863*67e74705SXin Li@property(retain) NSObject *inputIvar; 864*67e74705SXin Li@end 865*67e74705SXin Li 866*67e74705SXin Li@implementation NotMissingDeallocCIFilter // no-warning 867*67e74705SXin Li@synthesize inputIvar = inputIvar; 868*67e74705SXin Li@end 869