|  | // RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-ios4.0 -DMACOS=0 -verify %s | 
|  | // RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-macosx10.6.0 -DMACOS=1 -verify %s | 
|  | // RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s | 
|  |  | 
|  | #include "Inputs/system-header-simulator-for-objc-dealloc.h" | 
|  |  | 
|  | #define NON_ARC !__has_feature(objc_arc) | 
|  |  | 
|  | #if NON_ARC | 
|  | #define WEAK_ON_ARC | 
|  | #else | 
|  | #define WEAK_ON_ARC __weak | 
|  | #endif | 
|  |  | 
|  | // No diagnostics expected under ARC. | 
|  | #if !NON_ARC | 
|  | // expected-no-diagnostics | 
|  | #endif | 
|  |  | 
|  | // Do not warn about missing release in -dealloc for ivars. | 
|  |  | 
|  | @interface MyIvarClass1 : NSObject { | 
|  | NSObject *_ivar; | 
|  | } | 
|  | @end | 
|  |  | 
|  | @implementation MyIvarClass1 | 
|  | - (instancetype)initWithIvar:(NSObject *)ivar | 
|  | { | 
|  | self = [super init]; | 
|  | if (!self) | 
|  | return nil; | 
|  | #if NON_ARC | 
|  | _ivar = [ivar retain]; | 
|  | #endif | 
|  | return self; | 
|  | } | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyIvarClass2 : NSObject { | 
|  | NSObject *_ivar; | 
|  | } | 
|  | - (NSObject *)ivar; | 
|  | - (void)setIvar:(NSObject *)ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyIvarClass2 | 
|  | - (instancetype)init | 
|  | { | 
|  | self = [super init]; | 
|  | return self; | 
|  | } | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | - (NSObject *)ivar | 
|  | { | 
|  | return _ivar; | 
|  | } | 
|  | - (void)setIvar:(NSObject *)ivar | 
|  | { | 
|  | #if NON_ARC | 
|  | [_ivar release]; | 
|  | _ivar = [ivar retain]; | 
|  | #else | 
|  | _ivar = ivar; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | // Warn about missing release in -dealloc for properties. | 
|  |  | 
|  | @interface MyPropertyClass1 : NSObject | 
|  | @property (copy) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClass1 | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass1' was copied by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClass2 : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClass2 | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass2' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClass3 : NSObject { | 
|  | NSObject *_ivar; | 
|  | } | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClass3 | 
|  | @synthesize ivar = _ivar; | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass3' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  |  | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClass4 : NSObject { | 
|  | void (^_blockPropertyIvar)(void); | 
|  | } | 
|  | @property (copy) void (^blockProperty)(void); | 
|  | @property (copy) void (^blockProperty2)(void); | 
|  | @property (copy) void (^blockProperty3)(void); | 
|  |  | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClass4 | 
|  | @synthesize blockProperty = _blockPropertyIvar; | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [_blockProperty2 release]; | 
|  | Block_release(_blockProperty3); | 
|  |  | 
|  | [super dealloc]; // expected-warning {{The '_blockPropertyIvar' ivar in 'MyPropertyClass4' was copied by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClass5 : NSObject { | 
|  | WEAK_ON_ARC NSObject *_ivar; | 
|  | } | 
|  | @property (weak) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClass5 | 
|  | @synthesize ivar = _ivar; | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // no-warning because it is a weak property | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClassWithReturnInDealloc : NSObject { | 
|  | NSObject *_ivar; | 
|  | } | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClassWithReturnInDealloc | 
|  | @synthesize ivar = _ivar; | 
|  | - (void)dealloc | 
|  | { | 
|  | return; | 
|  | #if NON_ARC | 
|  | // expected-warning@-2{{The '_ivar' ivar in 'MyPropertyClassWithReturnInDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClassWithReleaseInOtherInstance : NSObject { | 
|  | NSObject *_ivar; | 
|  | MyPropertyClassWithReleaseInOtherInstance *_other; | 
|  | } | 
|  | @property (retain) NSObject *ivar; | 
|  |  | 
|  | -(void)releaseIvars; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClassWithReleaseInOtherInstance | 
|  | @synthesize ivar = _ivar; | 
|  |  | 
|  | -(void)releaseIvars; { | 
|  | #if NON_ARC | 
|  | [_ivar release]; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | - (void)dealloc | 
|  | { | 
|  | [_other releaseIvars]; | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClassWithReleaseInOtherInstance' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface MyPropertyClassWithNeitherReturnNorSuperDealloc : NSObject { | 
|  | NSObject *_ivar; | 
|  | } | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyPropertyClassWithNeitherReturnNorSuperDealloc | 
|  | @synthesize ivar = _ivar; | 
|  | - (void)dealloc | 
|  | { | 
|  | } | 
|  | #if NON_ARC | 
|  | // expected-warning@-2 {{method possibly missing a [super dealloc] call}} (From Sema) | 
|  | // expected-warning@-3{{The '_ivar' ivar in 'MyPropertyClassWithNeitherReturnNorSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | @end | 
|  |  | 
|  | // <rdar://problem/6380411>: 'myproperty' has kind 'assign' and thus the | 
|  | //  assignment through the setter does not perform a release. | 
|  |  | 
|  | @interface MyObject : NSObject { | 
|  | id __unsafe_unretained _myproperty; | 
|  | } | 
|  | @property(assign) id myproperty; | 
|  | @end | 
|  |  | 
|  | @implementation MyObject | 
|  | @synthesize myproperty=_myproperty; // no-warning | 
|  | - (void)dealloc { | 
|  | // Don't claim that myproperty is released since it the property | 
|  | // has the 'assign' attribute. | 
|  | self.myproperty = 0; // no-warning | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface ClassWithControlFlowInRelease : NSObject { | 
|  | BOOL _ivar1; | 
|  | } | 
|  | @property (retain) NSObject *ivar2; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithControlFlowInRelease | 
|  | - (void)dealloc; { | 
|  | if (_ivar1) { | 
|  | // We really should warn because there is a path through -dealloc on which | 
|  | // _ivar2 is not released. | 
|  | #if NON_ARC | 
|  | [_ivar2 release]; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar2' ivar in 'ClassWithControlFlowInRelease' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | // Don't warn when the property is nil'd out in -dealloc | 
|  |  | 
|  | @interface ClassWithNildOutProperty : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @property (assign) int *intPtrProp; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithNildOutProperty | 
|  | - (void)dealloc; { | 
|  | self.ivar = nil; | 
|  |  | 
|  | // Make sure to handle setting a non-retainable property to 0. | 
|  | self.intPtrProp = 0; | 
|  | #if NON_ARC | 
|  | [super dealloc];  // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | // Do warn when the ivar but not the property is nil'd out in -dealloc | 
|  |  | 
|  | @interface ClassWithNildOutIvar : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithNildOutIvar | 
|  | - (void)dealloc; { | 
|  | // Oops. Meant self.ivar = nil | 
|  | _ivar = nil; | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWithNildOutIvar' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | // Do warn when the ivar is updated to a different value that is then | 
|  | // released. | 
|  |  | 
|  | @interface ClassWithUpdatedIvar : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithUpdatedIvar | 
|  | - (void)dealloc; { | 
|  | _ivar = [[NSObject alloc] init]; | 
|  |  | 
|  | #if NON_ARC | 
|  | [_ivar release]; | 
|  | #endif | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWithUpdatedIvar' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | // Don't warn when the property is nil'd out with a setter in -dealloc | 
|  |  | 
|  | @interface ClassWithNildOutPropertyViaSetter : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithNildOutPropertyViaSetter | 
|  | - (void)dealloc; { | 
|  | [self setIvar:nil]; | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc];  // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | // Don't warn about missing releases when -dealloc helpers are called. | 
|  |  | 
|  | @interface ClassWithDeallocHelpers : NSObject | 
|  | @property (retain) NSObject *ivarReleasedInMethod; | 
|  | @property (retain) NSObject *propNilledOutInMethod; | 
|  |  | 
|  | @property (retain) NSObject *ivarReleasedInFunction; | 
|  | @property (retain) NSObject *propNilledOutInFunction; | 
|  |  | 
|  | @property (retain) NSObject *ivarNeverReleased; | 
|  | - (void)invalidateInMethod; | 
|  | @end | 
|  |  | 
|  | void ReleaseValueHelper(NSObject *iv) { | 
|  | #if NON_ARC | 
|  | [iv release]; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void NilOutPropertyHelper(ClassWithDeallocHelpers *o) { | 
|  | o.propNilledOutInFunction = nil; | 
|  | } | 
|  |  | 
|  | @implementation ClassWithDeallocHelpers | 
|  | - (void)invalidateInMethod { | 
|  | #if NON_ARC | 
|  | [_ivarReleasedInMethod release]; | 
|  | #endif | 
|  | self.propNilledOutInMethod = nil; | 
|  | } | 
|  |  | 
|  | - (void)dealloc; { | 
|  | ReleaseValueHelper(_ivarReleasedInFunction); | 
|  | NilOutPropertyHelper(self); | 
|  |  | 
|  | [self invalidateInMethod]; | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_ivarNeverReleased' ivar in 'ClassWithDeallocHelpers' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | // Don't warn when self in -dealloc escapes. | 
|  |  | 
|  | @interface ClassWhereSelfEscapesViaMethodCall : NSObject | 
|  | @property (retain) NSObject *ivar;  // no-warning | 
|  | @end | 
|  |  | 
|  | @interface ClassWhereSelfEscapesViaMethodCall (Other) | 
|  | - (void)invalidate; // In other translation unit. | 
|  | @end | 
|  |  | 
|  | @implementation ClassWhereSelfEscapesViaMethodCall | 
|  | - (void)dealloc; { | 
|  | [self invalidate]; | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } // no-warning | 
|  | @end | 
|  |  | 
|  | @interface ClassWhereSelfEscapesViaPropertyAccess : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @interface ClassWhereSelfEscapesViaPropertyAccess (Other) | 
|  | // The implementation of this property is unknown and therefore could | 
|  | // release ivar. | 
|  | @property (retain) NSObject *otherIvar; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWhereSelfEscapesViaPropertyAccess | 
|  | - (void)dealloc; { | 
|  | self.otherIvar = nil; | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } // no-warning | 
|  | @end | 
|  |  | 
|  | // Don't treat self as escaping when setter called on *synthesized* | 
|  | // property. | 
|  |  | 
|  | @interface ClassWhereSelfEscapesViaSynthesizedPropertyAccess : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @property (retain) NSObject *otherIvar; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWhereSelfEscapesViaSynthesizedPropertyAccess | 
|  | - (void)dealloc; { | 
|  | self.otherIvar = nil; | 
|  | #if NON_ARC | 
|  | [super dealloc];  // expected-warning {{The '_ivar' ivar in 'ClassWhereSelfEscapesViaSynthesizedPropertyAccess' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | // Don't treat calls to system headers as escapes | 
|  |  | 
|  | @interface ClassWhereSelfEscapesViaCallToSystem : NSObject | 
|  | @property (retain) NSObject *ivar1; | 
|  | @property (retain) NSObject *ivar2; | 
|  | @property (retain) NSObject *ivar3; | 
|  | @property (retain) NSObject *ivar4; | 
|  | @property (retain) NSObject *ivar5; | 
|  | @property (retain) NSObject *ivar6; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWhereSelfEscapesViaCallToSystem | 
|  | - (void)dealloc; { | 
|  | #if NON_ARC | 
|  | [_ivar2 release]; | 
|  | if (_ivar3) { | 
|  | [_ivar3 release]; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self]; | 
|  | [[NSNotificationCenter defaultCenter] removeObserver:self]; | 
|  |  | 
|  | #if NON_ARC | 
|  | [_ivar4 release]; | 
|  |  | 
|  | if (_ivar5) { | 
|  | [_ivar5 release]; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | [[NSNotificationCenter defaultCenter] removeObserver:self]; | 
|  |  | 
|  | #if NON_ARC | 
|  | if (_ivar6) { | 
|  | [_ivar6 release]; | 
|  | } | 
|  |  | 
|  | [super dealloc];  // expected-warning {{The '_ivar1' ivar in 'ClassWhereSelfEscapesViaCallToSystem' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | // Don't warn when value escapes. | 
|  |  | 
|  | @interface ClassWhereIvarValueEscapes : NSObject | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | void ReleaseMe(id arg); | 
|  |  | 
|  | @implementation ClassWhereIvarValueEscapes | 
|  | - (void)dealloc; { | 
|  |  | 
|  | ReleaseMe(_ivar); | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } // no-warning | 
|  | @end | 
|  |  | 
|  | // Don't warn when value is known to be nil. | 
|  |  | 
|  | @interface ClassWhereIvarIsNil : NSObject | 
|  | @property (retain) NSObject *ivarIsNil; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWhereIvarIsNil | 
|  | - (void)dealloc; { | 
|  |  | 
|  | #if NON_ARC | 
|  | if (_ivarIsNil) | 
|  | [_ivarIsNil release]; | 
|  |  | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } // no-warning | 
|  | @end | 
|  |  | 
|  |  | 
|  | // Don't warn for non-retainable properties. | 
|  |  | 
|  | @interface ClassWithNonRetainableProperty : NSObject | 
|  | @property (assign) int *ivar;  // no-warning | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithNonRetainableProperty | 
|  | - (void)dealloc; { | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } // no-warning | 
|  | @end | 
|  |  | 
|  |  | 
|  | @interface SuperClassOfClassWithInlinedSuperDealloc : NSObject | 
|  | @property (retain) NSObject *propInSuper; | 
|  | @end | 
|  |  | 
|  | @implementation SuperClassOfClassWithInlinedSuperDealloc | 
|  | - (void)dealloc { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_propInSuper' ivar in 'SuperClassOfClassWithInlinedSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface ClassWithInlinedSuperDealloc : SuperClassOfClassWithInlinedSuperDealloc | 
|  | @property (retain) NSObject *propInSub; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithInlinedSuperDealloc | 
|  | - (void)dealloc { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_propInSub' ivar in 'ClassWithInlinedSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | @interface SuperClassOfClassWithInlinedSuperDeallocAndInvalidation : NSObject | 
|  | @property (retain) NSObject *propInSuper; | 
|  |  | 
|  | - (void)invalidate; | 
|  | @end | 
|  |  | 
|  | @implementation SuperClassOfClassWithInlinedSuperDeallocAndInvalidation | 
|  |  | 
|  | - (void)invalidate { | 
|  | #if NON_ARC | 
|  | [_propInSuper release]; | 
|  | #endif | 
|  | _propInSuper = nil; | 
|  | } | 
|  |  | 
|  | - (void)dealloc { | 
|  | [self invalidate]; | 
|  | #if NON_ARC | 
|  | [super dealloc]; // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface ClassWithInlinedSuperDeallocAndInvalidation : SuperClassOfClassWithInlinedSuperDeallocAndInvalidation | 
|  | @property (retain) NSObject *propInSub; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithInlinedSuperDeallocAndInvalidation | 
|  |  | 
|  | - (void)invalidate { | 
|  | #if NON_ARC | 
|  | [_propInSub release]; | 
|  | #endif | 
|  | [super invalidate]; | 
|  | } | 
|  |  | 
|  | - (void)dealloc { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | @interface SuperClassOfClassThatEscapesBeforeInliningSuper : NSObject | 
|  | @property (retain) NSObject *propInSuper; | 
|  | @end | 
|  |  | 
|  | @implementation SuperClassOfClassThatEscapesBeforeInliningSuper | 
|  |  | 
|  | - (void)dealloc { | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; // expected-warning {{The '_propInSuper' ivar in 'SuperClassOfClassThatEscapesBeforeInliningSuper' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface ClassThatEscapesBeforeInliningSuper : SuperClassOfClassThatEscapesBeforeInliningSuper | 
|  | @property (retain) NSObject *propInSub; | 
|  | @end | 
|  |  | 
|  | @interface ClassThatEscapesBeforeInliningSuper (Other) | 
|  | - (void)invalidate; // No implementation in translation unit. | 
|  | @end | 
|  |  | 
|  | @implementation ClassThatEscapesBeforeInliningSuper | 
|  | - (void)dealloc { | 
|  | [self invalidate]; | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | #if NON_ARC | 
|  | @interface ReleaseIvarInField : NSObject { | 
|  | int _tag; | 
|  | union { | 
|  | NSObject *field1; | 
|  | NSObject *field2; | 
|  | } _someUnion; | 
|  |  | 
|  | struct { | 
|  | NSObject *field1; | 
|  | } _someStruct; | 
|  | } | 
|  | @end | 
|  |  | 
|  | @implementation ReleaseIvarInField | 
|  | - (void)dealloc { | 
|  | if (_tag) { | 
|  | [_someUnion.field1 release]; | 
|  | } else { | 
|  | [_someUnion.field2 release]; | 
|  | } | 
|  |  | 
|  | [_someStruct.field1 release]; | 
|  | [super dealloc]; | 
|  | } | 
|  | @end | 
|  | #endif | 
|  |  | 
|  | struct SomeStruct { | 
|  | int f; | 
|  | }; | 
|  | @interface ZeroOutStructWithSetter : NSObject | 
|  | @property(assign) struct SomeStruct s; | 
|  | @end | 
|  |  | 
|  | @implementation ZeroOutStructWithSetter | 
|  | - (void)dealloc { | 
|  | struct SomeStruct zeroedS; | 
|  | zeroedS.f = 0; | 
|  |  | 
|  | self.s = zeroedS; | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | #if NON_ARC | 
|  | @interface ReleaseIvarInArray : NSObject { | 
|  | NSObject *_array[3]; | 
|  | } | 
|  | @end | 
|  |  | 
|  | @implementation ReleaseIvarInArray | 
|  | - (void)dealloc { | 
|  | for (int i = 0; i < 3; i++) { | 
|  | [_array[i] release]; | 
|  | } | 
|  | [super dealloc]; | 
|  | } | 
|  | @end | 
|  | #endif | 
|  |  | 
|  | // Don't warn about missing releases for subclasses of SenTestCase or | 
|  | // for classes that are not subclasses of NSObject. | 
|  |  | 
|  | @interface SenTestCase : NSObject {} | 
|  | @end | 
|  |  | 
|  | @interface MyClassTest : SenTestCase | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyClassTest | 
|  | -(void)tearDown { | 
|  | #if NON_ARC | 
|  | [_ivar release]; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | -(void)dealloc; { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface XCTestCase : NSObject {} | 
|  | @end | 
|  |  | 
|  | @interface MyClassXCTest : XCTestCase | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation MyClassXCTest | 
|  | -(void)tearDown { | 
|  | #if NON_ARC | 
|  | [_ivar release]; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | -(void)dealloc; { | 
|  | #if NON_ARC | 
|  | [super dealloc]; // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | __attribute__((objc_root_class)) | 
|  | @interface NonNSObjectMissingDealloc | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  | @implementation NonNSObjectMissingDealloc | 
|  | -(void)dealloc; { | 
|  |  | 
|  | } | 
|  | @end | 
|  |  | 
|  | // Warn about calling -dealloc rather than release by mistake. | 
|  |  | 
|  | @interface CallDeallocOnRetainPropIvar : NSObject { | 
|  | NSObject *okToDeallocDirectly; | 
|  | } | 
|  |  | 
|  | @property (retain) NSObject *ivar; | 
|  | @end | 
|  |  | 
|  | @implementation CallDeallocOnRetainPropIvar | 
|  | - (void)dealloc | 
|  | { | 
|  | #if NON_ARC | 
|  | // Only warn for synthesized ivars. | 
|  | [okToDeallocDirectly dealloc]; // no-warning | 
|  | [_ivar dealloc];  // expected-warning {{'_ivar' should be released rather than deallocated}} | 
|  |  | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | // CIFilter special cases. | 
|  | // By design, -[CIFilter dealloc] releases (by calling -setValue: forKey: with | 
|  | // 'nil') all ivars (even in its *subclasses*) with names starting with | 
|  | // 'input' or that are backed by properties with names starting with 'input'. | 
|  | // The Dealloc checker needs to take particular care to not warn about missing | 
|  | // releases in this case -- if the user adds a release quiet the | 
|  | // warning it may result in an over release. | 
|  |  | 
|  | @interface ImmediateSubCIFilter : CIFilter { | 
|  | NSObject *inputIvar; | 
|  | NSObject *nonInputIvar; | 
|  | NSObject *notPrefixedButBackingPrefixedProperty; | 
|  | NSObject *inputPrefixedButBackingNonPrefixedProperty; | 
|  | } | 
|  |  | 
|  | @property(retain) NSObject *inputIvar; | 
|  | @property(retain) NSObject *nonInputIvar; | 
|  | @property(retain) NSObject *inputAutoSynthesizedIvar; | 
|  | @property(retain) NSObject *inputExplicitlySynthesizedToNonPrefixedIvar; | 
|  | @property(retain) NSObject *nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar; | 
|  |  | 
|  | @end | 
|  |  | 
|  | @implementation ImmediateSubCIFilter | 
|  | @synthesize inputIvar = inputIvar; | 
|  | @synthesize nonInputIvar = nonInputIvar; | 
|  | @synthesize inputExplicitlySynthesizedToNonPrefixedIvar = notPrefixedButBackingPrefixedProperty; | 
|  | @synthesize nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar = inputPrefixedButBackingNonPrefixedProperty; | 
|  |  | 
|  | - (void)dealloc { | 
|  | #if NON_ARC | 
|  | // We don't want warnings here for: | 
|  | // inputIvar | 
|  | // inputAutoSynthesizedIvar | 
|  | // inputExplicitlySynthesizedToNonPrefixedIvar | 
|  | // inputPrefixedButBackingNonPrefixedProperty | 
|  | [super dealloc]; | 
|  | // expected-warning@-1 {{The 'nonInputIvar' ivar in 'ImmediateSubCIFilter' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface SubSubCIFilter : CIFilter { | 
|  | NSObject *inputIvarInSub; | 
|  | } | 
|  |  | 
|  | @property(retain) NSObject *inputIvarInSub; | 
|  | @end | 
|  |  | 
|  | @implementation SubSubCIFilter | 
|  | @synthesize inputIvarInSub = inputIvarInSub; | 
|  |  | 
|  | - (void)dealloc { | 
|  | // Don't warn about inputIvarInSub. | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #endif | 
|  | } | 
|  | @end | 
|  | @interface OverreleasingCIFilter : CIFilter { | 
|  | NSObject *inputIvar; | 
|  | } | 
|  |  | 
|  | @property(retain) NSObject *inputIvar; | 
|  | @end | 
|  |  | 
|  | @implementation OverreleasingCIFilter | 
|  | @synthesize inputIvar = inputIvar; | 
|  |  | 
|  | - (void)dealloc { | 
|  | #if NON_ARC | 
|  | // This is an over release because CIFilter's dealloc will also release it. | 
|  | [inputIvar release]; // expected-warning {{The 'inputIvar' ivar in 'OverreleasingCIFilter' will be released by '-[CIFilter dealloc]' but also released here}} | 
|  | [super dealloc]; // no-warning | 
|  | #endif | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | @interface NotMissingDeallocCIFilter : CIFilter { | 
|  | NSObject *inputIvar; | 
|  | } | 
|  |  | 
|  | @property(retain) NSObject *inputIvar; | 
|  | @end | 
|  |  | 
|  | @implementation NotMissingDeallocCIFilter // no-warning | 
|  | @synthesize inputIvar = inputIvar; | 
|  | @end | 
|  |  | 
|  |  | 
|  | @interface ClassWithRetainPropWithIBOutletIvarButNoSetter : NSObject { | 
|  | // On macOS, the nib-loading code will set the ivar directly without | 
|  | // retaining value (unike iOS, where it is retained). This means that | 
|  | // on macOS we should not warn about a missing release for a property backed | 
|  | // by an IBOutlet ivar when that property does not have a setter. | 
|  | IBOutlet NSObject *ivarForOutlet; | 
|  | } | 
|  |  | 
|  | @property (readonly, retain) NSObject *ivarForOutlet; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithRetainPropWithIBOutletIvarButNoSetter | 
|  |  | 
|  | @synthesize ivarForOutlet; | 
|  | - (void)dealloc { | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | #if !MACOS | 
|  | // expected-warning@-2{{The 'ivarForOutlet' ivar in 'ClassWithRetainPropWithIBOutletIvarButNoSetter' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | #endif | 
|  | } | 
|  |  | 
|  | @end | 
|  |  | 
|  | @interface ClassWithRetainPropWithIBOutletIvarAndShadowingReadWrite : NSObject { | 
|  | IBOutlet NSObject *ivarForOutlet; | 
|  | } | 
|  |  | 
|  | @property (readonly, retain) NSObject *ivarForOutlet; | 
|  |  | 
|  | @end | 
|  |  | 
|  | @interface ClassWithRetainPropWithIBOutletIvarAndShadowingReadWrite () | 
|  |  | 
|  | // Since there is a shadowing readwrite property, there will be a retaining | 
|  | // setter and so the ivar will be retained by nib-loading code even on | 
|  | // macOS and therefore must be released. | 
|  | @property (readwrite, retain) NSObject *ivarForOutlet; | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithRetainPropWithIBOutletIvarAndShadowingReadWrite | 
|  |  | 
|  | @synthesize ivarForOutlet; | 
|  | - (void)dealloc { | 
|  |  | 
|  | #if NON_ARC | 
|  | [super dealloc]; | 
|  | // expected-warning@-1{{The 'ivarForOutlet' ivar in 'ClassWithRetainPropWithIBOutletIvarAndShadowingReadWrite' was retained by a synthesized property but not released before '[super dealloc]'}} | 
|  | #endif | 
|  | } | 
|  |  | 
|  | @end |