| // 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 |