forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			926 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
			
		
		
	
	
			926 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-ios4.0 -DMACOS=0 -verify %s
 | 
						|
// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-macosx10.6.0 -DMACOS=1 -verify %s
 | 
						|
// RUN: %clang_cc1 -analyze -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
 |