1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s 2*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s 3*67e74705SXin Li 4*67e74705SXin Livoid clang_analyzer_eval(int); 5*67e74705SXin Li 6*67e74705SXin Litypedef const void * CFTypeRef; 7*67e74705SXin Liextern CFTypeRef CFRetain(CFTypeRef cf); 8*67e74705SXin Livoid CFRelease(CFTypeRef cf); 9*67e74705SXin Li 10*67e74705SXin Litypedef signed char BOOL; 11*67e74705SXin Litypedef unsigned int NSUInteger; 12*67e74705SXin Litypedef struct _NSZone NSZone; 13*67e74705SXin Li@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 14*67e74705SXin Li@protocol NSObject - (BOOL)isEqual:(id)object; @end 15*67e74705SXin Li@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end 16*67e74705SXin Li@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end 17*67e74705SXin Li@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end 18*67e74705SXin Li@interface NSObject <NSObject> {} 19*67e74705SXin Li+(id)alloc; 20*67e74705SXin Li-(id)init; 21*67e74705SXin Li-(id)autorelease; 22*67e74705SXin Li-(id)copy; 23*67e74705SXin Li-(id)retain; 24*67e74705SXin Li-(oneway void)release; 25*67e74705SXin Li-(void)dealloc; 26*67e74705SXin Li@end 27*67e74705SXin Li@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> 28*67e74705SXin Li- (NSUInteger)length; 29*67e74705SXin Li-(id)initWithFormat:(NSString *)f,...; 30*67e74705SXin Li-(BOOL)isEqualToString:(NSString *)s; 31*67e74705SXin Li+ (id)string; 32*67e74705SXin Li@end 33*67e74705SXin Li@interface NSNumber : NSObject {} 34*67e74705SXin Li+(id)alloc; 35*67e74705SXin Li-(id)initWithInteger:(int)i; 36*67e74705SXin Li@end 37*67e74705SXin Li 38*67e74705SXin Li// rdar://6946338 39*67e74705SXin Li 40*67e74705SXin Li@interface Test1 : NSObject { 41*67e74705SXin Li NSString *text; 42*67e74705SXin Li} 43*67e74705SXin Li-(id)myMethod; 44*67e74705SXin Li@property (nonatomic, assign) NSString *text; 45*67e74705SXin Li@end 46*67e74705SXin Li 47*67e74705SXin Li 48*67e74705SXin Li#if !__has_feature(objc_arc) 49*67e74705SXin Li 50*67e74705SXin Li@implementation Test1 51*67e74705SXin Li 52*67e74705SXin Li@synthesize text; 53*67e74705SXin Li 54*67e74705SXin Li-(id)myMethod { 55*67e74705SXin Li Test1 *cell = [[[Test1 alloc] init] autorelease]; 56*67e74705SXin Li 57*67e74705SXin Li NSString *string1 = [[NSString alloc] initWithFormat:@"test %f", 0.0]; // expected-warning {{Potential leak}} 58*67e74705SXin Li cell.text = string1; 59*67e74705SXin Li 60*67e74705SXin Li return cell; 61*67e74705SXin Li} 62*67e74705SXin Li 63*67e74705SXin Li@end 64*67e74705SXin Li 65*67e74705SXin Li 66*67e74705SXin Li// rdar://8824416 67*67e74705SXin Li 68*67e74705SXin Li@interface MyNumber : NSObject 69*67e74705SXin Li{ 70*67e74705SXin Li NSNumber* _myNumber; 71*67e74705SXin Li} 72*67e74705SXin Li 73*67e74705SXin Li- (id)initWithNumber:(NSNumber *)number; 74*67e74705SXin Li 75*67e74705SXin Li@property (nonatomic, readonly) NSNumber* myNumber; 76*67e74705SXin Li@property (nonatomic, readonly) NSNumber* newMyNumber; 77*67e74705SXin Li 78*67e74705SXin Li@end 79*67e74705SXin Li 80*67e74705SXin Li@implementation MyNumber 81*67e74705SXin Li@synthesize myNumber=_myNumber; 82*67e74705SXin Li 83*67e74705SXin Li- (id)initWithNumber:(NSNumber *)number 84*67e74705SXin Li{ 85*67e74705SXin Li self = [super init]; 86*67e74705SXin Li 87*67e74705SXin Li if ( self ) 88*67e74705SXin Li { 89*67e74705SXin Li _myNumber = [number copy]; 90*67e74705SXin Li } 91*67e74705SXin Li 92*67e74705SXin Li return self; 93*67e74705SXin Li} 94*67e74705SXin Li 95*67e74705SXin Li- (NSNumber*)newMyNumber 96*67e74705SXin Li{ 97*67e74705SXin Li if ( _myNumber ) 98*67e74705SXin Li return [_myNumber retain]; 99*67e74705SXin Li 100*67e74705SXin Li return [[NSNumber alloc] initWithInteger:1]; 101*67e74705SXin Li} 102*67e74705SXin Li 103*67e74705SXin Li- (id)valueForUndefinedKey:(NSString*)key 104*67e74705SXin Li{ 105*67e74705SXin Li id value = 0; 106*67e74705SXin Li 107*67e74705SXin Li if ([key isEqualToString:@"MyIvarNumberAsPropertyOverReleased"]) 108*67e74705SXin Li value = self.myNumber; // _myNumber will be over released, since the value returned from self.myNumber is not retained. 109*67e74705SXin Li else if ([key isEqualToString:@"MyIvarNumberAsPropertyOk"]) 110*67e74705SXin Li value = [self.myNumber retain]; // this line fixes the over release 111*67e74705SXin Li else if ([key isEqualToString:@"MyIvarNumberAsNewMyNumber"]) 112*67e74705SXin Li value = self.newMyNumber; // this one is ok, since value is returned retained 113*67e74705SXin Li else 114*67e74705SXin Li value = [[NSNumber alloc] initWithInteger:0]; 115*67e74705SXin Li 116*67e74705SXin Li return [value autorelease]; // expected-warning {{Object autoreleased too many times}} 117*67e74705SXin Li} 118*67e74705SXin Li 119*67e74705SXin Li@end 120*67e74705SXin Li 121*67e74705SXin LiNSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber) 122*67e74705SXin Li{ 123*67e74705SXin Li NSNumber* result = aMyNumber.myNumber; 124*67e74705SXin Li 125*67e74705SXin Li return [result autorelease]; // expected-warning {{Object autoreleased too many times}} 126*67e74705SXin Li} 127*67e74705SXin Li 128*67e74705SXin Li#endif 129*67e74705SXin Li 130*67e74705SXin Li 131*67e74705SXin Li// rdar://6611873 132*67e74705SXin Li 133*67e74705SXin Li@interface Person : NSObject { 134*67e74705SXin Li NSString *_name; 135*67e74705SXin Li} 136*67e74705SXin Li@property (retain) NSString * name; 137*67e74705SXin Li@property (assign) id friend; 138*67e74705SXin Li@end 139*67e74705SXin Li 140*67e74705SXin Li@implementation Person 141*67e74705SXin Li@synthesize name = _name; 142*67e74705SXin Li 143*67e74705SXin Li-(void)dealloc { 144*67e74705SXin Li#if !__has_feature(objc_arc) 145*67e74705SXin Li self.name = [[NSString alloc] init]; // expected-warning {{leak}} 146*67e74705SXin Li 147*67e74705SXin Li [super dealloc]; // expected-warning {{The '_name' ivar in 'Person' was retained by a synthesized property but not released before '[super dealloc]}} 148*67e74705SXin Li#endif 149*67e74705SXin Li} 150*67e74705SXin Li@end 151*67e74705SXin Li 152*67e74705SXin Li#if !__has_feature(objc_arc) 153*67e74705SXin Livoid rdar6611873() { 154*67e74705SXin Li Person *p = [[[Person alloc] init] autorelease]; 155*67e74705SXin Li 156*67e74705SXin Li p.name = [[NSString string] retain]; // expected-warning {{leak}} 157*67e74705SXin Li p.name = [[NSString alloc] init]; // expected-warning {{leak}} 158*67e74705SXin Li 159*67e74705SXin Li p.friend = [[Person alloc] init]; // expected-warning {{leak}} 160*67e74705SXin Li} 161*67e74705SXin Li#endif 162*67e74705SXin Li 163*67e74705SXin Li@interface SubPerson : Person 164*67e74705SXin Li-(NSString *)foo; 165*67e74705SXin Li@end 166*67e74705SXin Li 167*67e74705SXin Li@implementation SubPerson 168*67e74705SXin Li-(NSString *)foo { 169*67e74705SXin Li return super.name; 170*67e74705SXin Li} 171*67e74705SXin Li@end 172*67e74705SXin Li 173*67e74705SXin Li 174*67e74705SXin Li#if !__has_feature(objc_arc) 175*67e74705SXin Li// <rdar://problem/9241180> Static analyzer doesn't detect uninitialized variable issues for property accesses 176*67e74705SXin Li@interface RDar9241180 177*67e74705SXin Li@property (readwrite,assign) id x; 178*67e74705SXin Li-(id)testAnalyzer1:(int) y; 179*67e74705SXin Li-(void)testAnalyzer2; 180*67e74705SXin Li@end 181*67e74705SXin Li 182*67e74705SXin Li@implementation RDar9241180 183*67e74705SXin Li@synthesize x; 184*67e74705SXin Li-(id)testAnalyzer1:(int)y { 185*67e74705SXin Li RDar9241180 *o; 186*67e74705SXin Li if (y && o.x) // expected-warning {{Property access on an uninitialized object pointer}} 187*67e74705SXin Li return o; 188*67e74705SXin Li return o; // expected-warning {{Undefined or garbage value returned to caller}} 189*67e74705SXin Li} 190*67e74705SXin Li-(void)testAnalyzer2 { 191*67e74705SXin Li id y; 192*67e74705SXin Li self.x = y; // expected-warning {{Argument for property setter is an uninitialized value}} 193*67e74705SXin Li} 194*67e74705SXin Li@end 195*67e74705SXin Li#endif 196*67e74705SXin Li 197*67e74705SXin Li 198*67e74705SXin Li//------ 199*67e74705SXin Li// Property accessor synthesis 200*67e74705SXin Li//------ 201*67e74705SXin Li 202*67e74705SXin Liextern void doSomethingWithPerson(Person *p); 203*67e74705SXin Liextern void doSomethingWithName(NSString *name); 204*67e74705SXin Li 205*67e74705SXin Livoid testConsistencyRetain(Person *p) { 206*67e74705SXin Li clang_analyzer_eval(p.name == p.name); // expected-warning{{TRUE}} 207*67e74705SXin Li 208*67e74705SXin Li id origName = p.name; 209*67e74705SXin Li clang_analyzer_eval(p.name == origName); // expected-warning{{TRUE}} 210*67e74705SXin Li doSomethingWithPerson(p); 211*67e74705SXin Li clang_analyzer_eval(p.name == origName); // expected-warning{{UNKNOWN}} 212*67e74705SXin Li} 213*67e74705SXin Li 214*67e74705SXin Livoid testConsistencyAssign(Person *p) { 215*67e74705SXin Li clang_analyzer_eval(p.friend == p.friend); // expected-warning{{TRUE}} 216*67e74705SXin Li 217*67e74705SXin Li id origFriend = p.friend; 218*67e74705SXin Li clang_analyzer_eval(p.friend == origFriend); // expected-warning{{TRUE}} 219*67e74705SXin Li doSomethingWithPerson(p); 220*67e74705SXin Li clang_analyzer_eval(p.friend == origFriend); // expected-warning{{UNKNOWN}} 221*67e74705SXin Li} 222*67e74705SXin Li 223*67e74705SXin Li@interface ClassWithShadowedReadWriteProperty { 224*67e74705SXin Li int _f; 225*67e74705SXin Li} 226*67e74705SXin Li@property (readonly) int someProp; 227*67e74705SXin Li@end 228*67e74705SXin Li 229*67e74705SXin Li@interface ClassWithShadowedReadWriteProperty () 230*67e74705SXin Li@property (readwrite) int someProp; 231*67e74705SXin Li@end 232*67e74705SXin Li 233*67e74705SXin Li@implementation ClassWithShadowedReadWriteProperty 234*67e74705SXin Li- (void)testSynthesisForShadowedReadWriteProperties; { 235*67e74705SXin Li clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}} 236*67e74705SXin Li 237*67e74705SXin Li _f = 1; 238*67e74705SXin Li 239*67e74705SXin Li // Read of shadowed property should not invalidate receiver. 240*67e74705SXin Li (void)self.someProp; 241*67e74705SXin Li clang_analyzer_eval(_f == 1); // expected-warning{{TRUE}} 242*67e74705SXin Li 243*67e74705SXin Li _f = 2; 244*67e74705SXin Li // Call to getter of shadowed property should not invalidate receiver. 245*67e74705SXin Li (void)[self someProp]; 246*67e74705SXin Li clang_analyzer_eval(_f == 2); // expected-warning{{TRUE}} 247*67e74705SXin Li} 248*67e74705SXin Li@end 249*67e74705SXin Li 250*67e74705SXin Li// Tests for the analyzer fix that works around a Sema bug 251*67e74705SXin Li// where multiple methods are created for properties in class extensions that 252*67e74705SXin Li// are redeclared in a category method. 253*67e74705SXin Li// The Sema bug is tracked as <rdar://problem/25481164>. 254*67e74705SXin Li@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory 255*67e74705SXin Li@end 256*67e74705SXin Li 257*67e74705SXin Li@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory () 258*67e74705SXin Li@end 259*67e74705SXin Li 260*67e74705SXin Li@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory () 261*67e74705SXin Li@property (readwrite) int someProp; 262*67e74705SXin Li@property (readonly) int otherProp; 263*67e74705SXin Li@end 264*67e74705SXin Li 265*67e74705SXin Li@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory (MyCat) 266*67e74705SXin Li@property (readonly) int someProp; 267*67e74705SXin Li@property (readonly) int otherProp; 268*67e74705SXin Li@end 269*67e74705SXin Li 270*67e74705SXin Li@implementation ClassWithRedeclaredPropertyInExtensionFollowedByCategory 271*67e74705SXin Li- (void)testSynthesisForRedeclaredProperties; { 272*67e74705SXin Li clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}} 273*67e74705SXin Li clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}} 274*67e74705SXin Li 275*67e74705SXin Li clang_analyzer_eval(self.otherProp == self.otherProp); // expected-warning{{TRUE}} 276*67e74705SXin Li clang_analyzer_eval([self otherProp] == self.otherProp); // expected-warning{{TRUE}} 277*67e74705SXin Li} 278*67e74705SXin Li@end 279*67e74705SXin Li 280*67e74705SXin Li// The relative order of the extension and the category matter, so test both. 281*67e74705SXin Li@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension 282*67e74705SXin Li@end 283*67e74705SXin Li 284*67e74705SXin Li@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension () 285*67e74705SXin Li@property (readwrite) int someProp; 286*67e74705SXin Li@end 287*67e74705SXin Li 288*67e74705SXin Li@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension (MyCat) 289*67e74705SXin Li@property (readonly) int someProp; 290*67e74705SXin Li@end 291*67e74705SXin Li 292*67e74705SXin Li@implementation ClassWithRedeclaredPropertyInCategoryFollowedByExtension 293*67e74705SXin Li- (void)testSynthesisForRedeclaredProperties; { 294*67e74705SXin Li clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}} 295*67e74705SXin Li clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}} 296*67e74705SXin Li} 297*67e74705SXin Li@end 298*67e74705SXin Li 299*67e74705SXin Li@interface ClassWithSynthesizedPropertyAndGetter 300*67e74705SXin Li@property (readonly) int someProp; 301*67e74705SXin Li@end 302*67e74705SXin Li 303*67e74705SXin Li@implementation ClassWithSynthesizedPropertyAndGetter 304*67e74705SXin Li@synthesize someProp; 305*67e74705SXin Li 306*67e74705SXin Li// Make sure that the actual getter is inlined and not a getter created 307*67e74705SXin Li// by BodyFarm 308*67e74705SXin Li- (void)testBodyFarmGetterNotUsed { 309*67e74705SXin Li int i = self.someProp; 310*67e74705SXin Li clang_analyzer_eval(i == 22); // expected-warning {{TRUE}} 311*67e74705SXin Li} 312*67e74705SXin Li 313*67e74705SXin Li-(int)someProp { 314*67e74705SXin Li return 22; 315*67e74705SXin Li} 316*67e74705SXin Li@end 317*67e74705SXin Li 318*67e74705SXin Li//------ 319*67e74705SXin Li// Setter ivar invalidation. 320*67e74705SXin Li//------ 321*67e74705SXin Li 322*67e74705SXin Li@interface ClassWithSetters 323*67e74705SXin Li// Note: These properties have implicit @synthesize implementations to be 324*67e74705SXin Li// backed with ivars. 325*67e74705SXin Li@property (assign) int propWithIvar1; 326*67e74705SXin Li@property (assign) int propWithIvar2; 327*67e74705SXin Li 328*67e74705SXin Li@property (retain) NSNumber *retainedProperty; 329*67e74705SXin Li 330*67e74705SXin Li@end 331*67e74705SXin Li 332*67e74705SXin Li@interface ClassWithSetters (InOtherTranslationUnit) 333*67e74705SXin Li// The implementation of this property is in another translation unit. 334*67e74705SXin Li// We don't know whether it is backed by an ivar or not. 335*67e74705SXin Li@property (assign) int propInOther; 336*67e74705SXin Li@end 337*67e74705SXin Li 338*67e74705SXin Li@implementation ClassWithSetters 339*67e74705SXin Li- (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; { 340*67e74705SXin Li _propWithIvar1 = 1; 341*67e74705SXin Li _propWithIvar2 = 2; 342*67e74705SXin Li self.propWithIvar1 = 66; 343*67e74705SXin Li 344*67e74705SXin Li // Calling the setter of a property backed by the instance variable 345*67e74705SXin Li // should invalidate the storage for the instance variable but not 346*67e74705SXin Li // the rest of the receiver. Ideally we would model the setter completely 347*67e74705SXin Li // but doing so would cause the new value to escape when it is bound 348*67e74705SXin Li // to the ivar. This would cause bad false negatives in the retain count 349*67e74705SXin Li // checker. (There is a test for this scenario in 350*67e74705SXin Li // testWriteRetainedValueToRetainedProperty below). 351*67e74705SXin Li clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 352*67e74705SXin Li clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{TRUE}} 353*67e74705SXin Li 354*67e74705SXin Li _propWithIvar1 = 1; 355*67e74705SXin Li [self setPropWithIvar1:66]; 356*67e74705SXin Li 357*67e74705SXin Li clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 358*67e74705SXin Li clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{TRUE}} 359*67e74705SXin Li} 360*67e74705SXin Li 361*67e74705SXin Li- (void) testSettingPropWithoutIvarInvalidatesEntireInstance; { 362*67e74705SXin Li _propWithIvar1 = 1; 363*67e74705SXin Li _propWithIvar2 = 2; 364*67e74705SXin Li self.propInOther = 66; 365*67e74705SXin Li 366*67e74705SXin Li clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 367*67e74705SXin Li clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{UNKNOWN}} 368*67e74705SXin Li 369*67e74705SXin Li _propWithIvar1 = 1; 370*67e74705SXin Li _propWithIvar2 = 2; 371*67e74705SXin Li [self setPropInOther:66]; 372*67e74705SXin Li 373*67e74705SXin Li clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 374*67e74705SXin Li clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{UNKNOWN}} 375*67e74705SXin Li} 376*67e74705SXin Li 377*67e74705SXin Li#if !__has_feature(objc_arc) 378*67e74705SXin Li- (void) testWriteRetainedValueToRetainedProperty; { 379*67e74705SXin Li NSNumber *number = [[NSNumber alloc] initWithInteger:5]; // expected-warning {{Potential leak of an object stored into 'number'}} 380*67e74705SXin Li 381*67e74705SXin Li // Make sure we catch this leak. 382*67e74705SXin Li self.retainedProperty = number; 383*67e74705SXin Li} 384*67e74705SXin Li#endif 385*67e74705SXin Li@end 386*67e74705SXin Li 387*67e74705SXin Li//------ 388*67e74705SXin Li// class properties 389*67e74705SXin Li//------ 390*67e74705SXin Li 391*67e74705SXin Liint gBackingForReadWriteClassProp = 0; 392*67e74705SXin Li 393*67e74705SXin Li@interface ClassWithClassProperties 394*67e74705SXin Li@property(class, readonly) int readOnlyClassProp; 395*67e74705SXin Li 396*67e74705SXin Li@property(class) int readWriteClassProp; 397*67e74705SXin Li 398*67e74705SXin Li// Make sure we handle when a class and instance property have the same 399*67e74705SXin Li// name. Test both when instance comes first and when class comes first. 400*67e74705SXin Li@property(readonly) int classAndInstancePropWithSameNameOrderInstanceFirst; 401*67e74705SXin Li@property(class, readonly) int classAndInstancePropWithSameNameOrderInstanceFirst; 402*67e74705SXin Li 403*67e74705SXin Li@property(class, readonly) int classAndInstancePropWithSameNameOrderClassFirst; 404*67e74705SXin Li@property(readonly) int classAndInstancePropWithSameNameOrderClassFirst; 405*67e74705SXin Li 406*67e74705SXin Li 407*67e74705SXin Li@property(class, readonly) int dynamicClassProp; 408*67e74705SXin Li 409*67e74705SXin Li@end 410*67e74705SXin Li 411*67e74705SXin Li@interface ClassWithClassProperties (OtherTranslationUnit) 412*67e74705SXin Li@property(class, assign) id propInOtherTranslationUnit; 413*67e74705SXin Li@end 414*67e74705SXin Li 415*67e74705SXin Li@implementation ClassWithClassProperties 416*67e74705SXin Li 417*67e74705SXin Li@dynamic dynamicClassProp; 418*67e74705SXin Li 419*67e74705SXin Li+ (int)readOnlyClassProp { 420*67e74705SXin Li return 1; 421*67e74705SXin Li} 422*67e74705SXin Li 423*67e74705SXin Li+ (int)readWriteClassProp { 424*67e74705SXin Li return gBackingForReadWriteClassProp; 425*67e74705SXin Li} 426*67e74705SXin Li 427*67e74705SXin Li+ (void)setReadWriteClassProp:(int)val { 428*67e74705SXin Li gBackingForReadWriteClassProp = val; 429*67e74705SXin Li} 430*67e74705SXin Li 431*67e74705SXin Li- (int)classAndInstancePropWithSameNameOrderInstanceFirst { 432*67e74705SXin Li return 12; 433*67e74705SXin Li} 434*67e74705SXin Li 435*67e74705SXin Li+ (int)classAndInstancePropWithSameNameOrderInstanceFirst { 436*67e74705SXin Li return 13; 437*67e74705SXin Li} 438*67e74705SXin Li 439*67e74705SXin Li+ (int)classAndInstancePropWithSameNameOrderClassFirst { 440*67e74705SXin Li return 14; 441*67e74705SXin Li} 442*67e74705SXin Li 443*67e74705SXin Li- (int)classAndInstancePropWithSameNameOrderClassFirst { 444*67e74705SXin Li return 15; 445*67e74705SXin Li} 446*67e74705SXin Li 447*67e74705SXin Li- (void)testInlineClassProp { 448*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.readOnlyClassProp == 1); // expected-warning{{TRUE}} 449*67e74705SXin Li 450*67e74705SXin Li ClassWithClassProperties.readWriteClassProp = 7; 451*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 7); // expected-warning{{TRUE}} 452*67e74705SXin Li ClassWithClassProperties.readWriteClassProp = 8; 453*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 8); // expected-warning{{TRUE}} 454*67e74705SXin Li} 455*67e74705SXin Li 456*67e74705SXin Li- (void)testUnknownClassProp { 457*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.propInOtherTranslationUnit == ClassWithClassProperties.propInOtherTranslationUnit); // expected-warning{{UNKNOWN}} 458*67e74705SXin Li} 459*67e74705SXin Li 460*67e74705SXin Li- (void)testEscapeGlobalOnUnknownProp { 461*67e74705SXin Li gBackingForReadWriteClassProp = 33; 462*67e74705SXin Li ClassWithClassProperties.propInOtherTranslationUnit = 0; 463*67e74705SXin Li clang_analyzer_eval(gBackingForReadWriteClassProp == 33); // expected-warning{{UNKNOWN}} 464*67e74705SXin Li} 465*67e74705SXin Li 466*67e74705SXin Li- (void)testClassAndInstancePropertyWithSameName { 467*67e74705SXin Li clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderInstanceFirst == 12); // expected-warning{{TRUE}} 468*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderInstanceFirst == 13); // expected-warning{{TRUE}} 469*67e74705SXin Li 470*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderClassFirst == 14); // expected-warning{{TRUE}} 471*67e74705SXin Li clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderClassFirst == 15); // expected-warning{{TRUE}} 472*67e74705SXin Li} 473*67e74705SXin Li 474*67e74705SXin Li- (void)testDynamicClassProp { 475*67e74705SXin Li clang_analyzer_eval(ClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{UNKNOWN}} 476*67e74705SXin Li} 477*67e74705SXin Li 478*67e74705SXin Li@end 479*67e74705SXin Li 480*67e74705SXin Li@interface SubclassOfClassWithClassProperties : ClassWithClassProperties 481*67e74705SXin Li@end 482*67e74705SXin Li 483*67e74705SXin Li@implementation SubclassOfClassWithClassProperties 484*67e74705SXin Li+ (int)dynamicClassProp; { 485*67e74705SXin Li return 16; 486*67e74705SXin Li} 487*67e74705SXin Li 488*67e74705SXin Li- (void)testDynamicClassProp { 489*67e74705SXin Li clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}} 490*67e74705SXin Li} 491*67e74705SXin Li 492*67e74705SXin Li@end 493*67e74705SXin Li 494*67e74705SXin Li 495*67e74705SXin Li#if !__has_feature(objc_arc) 496*67e74705SXin Livoid testOverrelease(Person *p, int coin) { 497*67e74705SXin Li switch (coin) { 498*67e74705SXin Li case 0: 499*67e74705SXin Li [p.name release]; // expected-warning{{not owned}} 500*67e74705SXin Li break; 501*67e74705SXin Li case 1: 502*67e74705SXin Li [p.friend release]; // expected-warning{{not owned}} 503*67e74705SXin Li break; 504*67e74705SXin Li case 2: { 505*67e74705SXin Li id friend = p.friend; 506*67e74705SXin Li doSomethingWithPerson(p); 507*67e74705SXin Li [friend release]; // expected-warning{{not owned}} 508*67e74705SXin Li } 509*67e74705SXin Li } 510*67e74705SXin Li} 511*67e74705SXin Li 512*67e74705SXin Li// <rdar://problem/16333368> 513*67e74705SXin Li@implementation Person (Rdar16333368) 514*67e74705SXin Li 515*67e74705SXin Li- (void)testDeliberateRelease:(Person *)other { 516*67e74705SXin Li doSomethingWithName(self.name); 517*67e74705SXin Li [_name release]; // no-warning 518*67e74705SXin Li self->_name = 0; 519*67e74705SXin Li 520*67e74705SXin Li doSomethingWithName(other->_name); 521*67e74705SXin Li [other.name release]; // no-warning 522*67e74705SXin Li} 523*67e74705SXin Li 524*67e74705SXin Li- (void)deliberateReleaseFalseNegative { 525*67e74705SXin Li // This is arguably a false negative because the result of p.friend shouldn't 526*67e74705SXin Li // be released, even though we are manipulating the ivar in between the two 527*67e74705SXin Li // actions. 528*67e74705SXin Li id name = self.name; 529*67e74705SXin Li _name = 0; 530*67e74705SXin Li [name release]; 531*67e74705SXin Li} 532*67e74705SXin Li 533*67e74705SXin Li- (void)testRetainAndRelease { 534*67e74705SXin Li [self.name retain]; 535*67e74705SXin Li [self.name release]; 536*67e74705SXin Li [self.name release]; // expected-warning{{not owned}} 537*67e74705SXin Li} 538*67e74705SXin Li 539*67e74705SXin Li- (void)testRetainAndReleaseIVar { 540*67e74705SXin Li [self.name retain]; 541*67e74705SXin Li [_name release]; 542*67e74705SXin Li [_name release]; 543*67e74705SXin Li} 544*67e74705SXin Li 545*67e74705SXin Li@end 546*67e74705SXin Li#endif 547*67e74705SXin Li 548*67e74705SXin Li@interface IntWrapper 549*67e74705SXin Li@property int value; 550*67e74705SXin Li@end 551*67e74705SXin Li 552*67e74705SXin Li@implementation IntWrapper 553*67e74705SXin Li@synthesize value; 554*67e74705SXin Li@end 555*67e74705SXin Li 556*67e74705SXin Livoid testConsistencyInt(IntWrapper *w) { 557*67e74705SXin Li clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}} 558*67e74705SXin Li 559*67e74705SXin Li int origValue = w.value; 560*67e74705SXin Li if (origValue != 42) 561*67e74705SXin Li return; 562*67e74705SXin Li 563*67e74705SXin Li clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 564*67e74705SXin Li} 565*67e74705SXin Li 566*67e74705SXin Livoid testConsistencyInt2(IntWrapper *w) { 567*67e74705SXin Li if (w.value != 42) 568*67e74705SXin Li return; 569*67e74705SXin Li 570*67e74705SXin Li clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 571*67e74705SXin Li} 572*67e74705SXin Li 573*67e74705SXin Li 574*67e74705SXin Li@interface IntWrapperAuto 575*67e74705SXin Li@property int value; 576*67e74705SXin Li@end 577*67e74705SXin Li 578*67e74705SXin Li@implementation IntWrapperAuto 579*67e74705SXin Li@end 580*67e74705SXin Li 581*67e74705SXin Livoid testConsistencyIntAuto(IntWrapperAuto *w) { 582*67e74705SXin Li clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}} 583*67e74705SXin Li 584*67e74705SXin Li int origValue = w.value; 585*67e74705SXin Li if (origValue != 42) 586*67e74705SXin Li return; 587*67e74705SXin Li 588*67e74705SXin Li clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 589*67e74705SXin Li} 590*67e74705SXin Li 591*67e74705SXin Livoid testConsistencyIntAuto2(IntWrapperAuto *w) { 592*67e74705SXin Li if (w.value != 42) 593*67e74705SXin Li return; 594*67e74705SXin Li 595*67e74705SXin Li clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 596*67e74705SXin Li} 597*67e74705SXin Li 598*67e74705SXin Li 599*67e74705SXin Litypedef struct { 600*67e74705SXin Li int value; 601*67e74705SXin Li} IntWrapperStruct; 602*67e74705SXin Li 603*67e74705SXin Li@interface StructWrapper 604*67e74705SXin Li@property IntWrapperStruct inner; 605*67e74705SXin Li@end 606*67e74705SXin Li 607*67e74705SXin Li@implementation StructWrapper 608*67e74705SXin Li@synthesize inner; 609*67e74705SXin Li@end 610*67e74705SXin Li 611*67e74705SXin Livoid testConsistencyStruct(StructWrapper *w) { 612*67e74705SXin Li clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}} 613*67e74705SXin Li 614*67e74705SXin Li int origValue = w.inner.value; 615*67e74705SXin Li if (origValue != 42) 616*67e74705SXin Li return; 617*67e74705SXin Li 618*67e74705SXin Li clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}} 619*67e74705SXin Li} 620*67e74705SXin Li 621*67e74705SXin Li 622*67e74705SXin Li@interface OpaqueIntWrapper 623*67e74705SXin Li@property int value; 624*67e74705SXin Li@end 625*67e74705SXin Li 626*67e74705SXin Li// For now, don't assume a property is implemented using an ivar unless we can 627*67e74705SXin Li// actually see that it is. 628*67e74705SXin Livoid testOpaqueConsistency(OpaqueIntWrapper *w) { 629*67e74705SXin Li clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}} 630*67e74705SXin Li} 631*67e74705SXin Li 632*67e74705SXin Li 633*67e74705SXin Li#if !__has_feature(objc_arc) 634*67e74705SXin Li// Test quite a few cases of retain/release issues. 635*67e74705SXin Li 636*67e74705SXin Li@interface RetainCountTesting 637*67e74705SXin Li@property (strong) id ownedProp; 638*67e74705SXin Li@property (unsafe_unretained) id unownedProp; 639*67e74705SXin Li@property (nonatomic, strong) id manualProp; 640*67e74705SXin Li@property (readonly) id readonlyProp; 641*67e74705SXin Li@property (nonatomic, readwrite/*, assign */) id implicitManualProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}} 642*67e74705SXin Li@property (nonatomic, readwrite/*, assign */) id implicitSynthProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}} 643*67e74705SXin Li@property CFTypeRef cfProp; 644*67e74705SXin Li@end 645*67e74705SXin Li 646*67e74705SXin Li@implementation RetainCountTesting { 647*67e74705SXin Li id _ivarOnly; 648*67e74705SXin Li} 649*67e74705SXin Li 650*67e74705SXin Li- (id)manualProp { 651*67e74705SXin Li return _manualProp; 652*67e74705SXin Li} 653*67e74705SXin Li 654*67e74705SXin Li- (void)setImplicitManualProp:(id)newValue {} 655*67e74705SXin Li 656*67e74705SXin Li- (void)testOverreleaseOwnedIvar { 657*67e74705SXin Li [_ownedProp retain]; 658*67e74705SXin Li [_ownedProp release]; 659*67e74705SXin Li [_ownedProp release]; 660*67e74705SXin Li [_ownedProp release]; // FIXME-warning{{used after it is released}} 661*67e74705SXin Li} 662*67e74705SXin Li 663*67e74705SXin Li- (void)testOverreleaseUnownedIvar { 664*67e74705SXin Li [_unownedProp retain]; 665*67e74705SXin Li [_unownedProp release]; 666*67e74705SXin Li [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}} 667*67e74705SXin Li} 668*67e74705SXin Li 669*67e74705SXin Li- (void)testOverreleaseIvarOnly { 670*67e74705SXin Li [_ivarOnly retain]; 671*67e74705SXin Li [_ivarOnly release]; 672*67e74705SXin Li [_ivarOnly release]; 673*67e74705SXin Li [_ivarOnly release]; // FIXME-warning{{used after it is released}} 674*67e74705SXin Li} 675*67e74705SXin Li 676*67e74705SXin Li- (void)testOverreleaseReadonlyIvar { 677*67e74705SXin Li [_readonlyProp retain]; 678*67e74705SXin Li [_readonlyProp release]; 679*67e74705SXin Li [_readonlyProp release]; 680*67e74705SXin Li [_readonlyProp release]; // FIXME-warning{{used after it is released}} 681*67e74705SXin Li} 682*67e74705SXin Li 683*67e74705SXin Li- (void)testOverreleaseImplicitManualIvar { 684*67e74705SXin Li [_implicitManualProp retain]; 685*67e74705SXin Li [_implicitManualProp release]; 686*67e74705SXin Li [_implicitManualProp release]; 687*67e74705SXin Li [_implicitManualProp release]; // FIXME-warning{{used after it is released}} 688*67e74705SXin Li} 689*67e74705SXin Li 690*67e74705SXin Li- (void)testOverreleaseImplicitSynthIvar { 691*67e74705SXin Li [_implicitSynthProp retain]; 692*67e74705SXin Li [_implicitSynthProp release]; 693*67e74705SXin Li [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}} 694*67e74705SXin Li} 695*67e74705SXin Li 696*67e74705SXin Li- (void)testOverreleaseCF { 697*67e74705SXin Li CFRetain(_cfProp); 698*67e74705SXin Li CFRelease(_cfProp); 699*67e74705SXin Li CFRelease(_cfProp); 700*67e74705SXin Li CFRelease(_cfProp); // FIXME-warning{{used after it is released}} 701*67e74705SXin Li} 702*67e74705SXin Li 703*67e74705SXin Li- (void)testOverreleaseOwnedIvarUse { 704*67e74705SXin Li [_ownedProp retain]; 705*67e74705SXin Li [_ownedProp release]; 706*67e74705SXin Li [_ownedProp release]; 707*67e74705SXin Li [_ownedProp myMethod]; // FIXME-warning{{used after it is released}} 708*67e74705SXin Li} 709*67e74705SXin Li 710*67e74705SXin Li- (void)testOverreleaseIvarOnlyUse { 711*67e74705SXin Li [_ivarOnly retain]; 712*67e74705SXin Li [_ivarOnly release]; 713*67e74705SXin Li [_ivarOnly release]; 714*67e74705SXin Li [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}} 715*67e74705SXin Li} 716*67e74705SXin Li 717*67e74705SXin Li- (void)testOverreleaseCFUse { 718*67e74705SXin Li CFRetain(_cfProp); 719*67e74705SXin Li CFRelease(_cfProp); 720*67e74705SXin Li CFRelease(_cfProp); 721*67e74705SXin Li 722*67e74705SXin Li extern void CFUse(CFTypeRef); 723*67e74705SXin Li CFUse(_cfProp); // FIXME-warning{{used after it is released}} 724*67e74705SXin Li} 725*67e74705SXin Li 726*67e74705SXin Li- (void)testOverreleaseOwnedIvarAutoreleaseOkay { 727*67e74705SXin Li [_ownedProp retain]; 728*67e74705SXin Li [_ownedProp release]; 729*67e74705SXin Li [_ownedProp autorelease]; 730*67e74705SXin Li} // no-warning 731*67e74705SXin Li 732*67e74705SXin Li- (void)testOverreleaseIvarOnlyAutoreleaseOkay { 733*67e74705SXin Li [_ivarOnly retain]; 734*67e74705SXin Li [_ivarOnly release]; 735*67e74705SXin Li [_ivarOnly autorelease]; 736*67e74705SXin Li} // no-warning 737*67e74705SXin Li 738*67e74705SXin Li- (void)testOverreleaseOwnedIvarAutorelease { 739*67e74705SXin Li [_ownedProp retain]; 740*67e74705SXin Li [_ownedProp release]; 741*67e74705SXin Li [_ownedProp autorelease]; 742*67e74705SXin Li [_ownedProp autorelease]; 743*67e74705SXin Li} // FIXME-warning{{Object autoreleased too many times}} 744*67e74705SXin Li 745*67e74705SXin Li- (void)testOverreleaseIvarOnlyAutorelease { 746*67e74705SXin Li [_ivarOnly retain]; 747*67e74705SXin Li [_ivarOnly release]; 748*67e74705SXin Li [_ivarOnly autorelease]; 749*67e74705SXin Li [_ivarOnly autorelease]; 750*67e74705SXin Li} // FIXME-warning{{Object autoreleased too many times}} 751*67e74705SXin Li 752*67e74705SXin Li- (void)testPropertyAccessThenReleaseOwned { 753*67e74705SXin Li id owned = [self.ownedProp retain]; 754*67e74705SXin Li [owned release]; 755*67e74705SXin Li [_ownedProp release]; 756*67e74705SXin Li clang_analyzer_eval(owned == _ownedProp); // expected-warning{{TRUE}} 757*67e74705SXin Li} 758*67e74705SXin Li 759*67e74705SXin Li- (void)testPropertyAccessThenReleaseOwned2 { 760*67e74705SXin Li id fromIvar = _ownedProp; 761*67e74705SXin Li id owned = [self.ownedProp retain]; 762*67e74705SXin Li [owned release]; 763*67e74705SXin Li [fromIvar release]; 764*67e74705SXin Li clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}} 765*67e74705SXin Li} 766*67e74705SXin Li 767*67e74705SXin Li- (void)testPropertyAccessThenReleaseUnowned { 768*67e74705SXin Li id unowned = [self.unownedProp retain]; 769*67e74705SXin Li [unowned release]; 770*67e74705SXin Li [_unownedProp release]; // FIXME-warning{{not owned}} 771*67e74705SXin Li} 772*67e74705SXin Li 773*67e74705SXin Li- (void)testPropertyAccessThenReleaseUnowned2 { 774*67e74705SXin Li id fromIvar = _unownedProp; 775*67e74705SXin Li id unowned = [self.unownedProp retain]; 776*67e74705SXin Li [unowned release]; 777*67e74705SXin Li clang_analyzer_eval(unowned == fromIvar); // expected-warning{{TRUE}} 778*67e74705SXin Li [fromIvar release]; // FIXME-warning{{not owned}} 779*67e74705SXin Li} 780*67e74705SXin Li 781*67e74705SXin Li- (void)testPropertyAccessThenReleaseManual { 782*67e74705SXin Li id prop = [self.manualProp retain]; 783*67e74705SXin Li [prop release]; 784*67e74705SXin Li [_manualProp release]; // no-warning 785*67e74705SXin Li} 786*67e74705SXin Li 787*67e74705SXin Li- (void)testPropertyAccessThenReleaseManual2 { 788*67e74705SXin Li id fromIvar = _manualProp; 789*67e74705SXin Li id prop = [self.manualProp retain]; 790*67e74705SXin Li [prop release]; 791*67e74705SXin Li clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 792*67e74705SXin Li [fromIvar release]; // no-warning 793*67e74705SXin Li} 794*67e74705SXin Li 795*67e74705SXin Li- (void)testPropertyAccessThenReleaseCF { 796*67e74705SXin Li CFTypeRef owned = CFRetain(self.cfProp); 797*67e74705SXin Li CFRelease(owned); 798*67e74705SXin Li CFRelease(_cfProp); // no-warning 799*67e74705SXin Li clang_analyzer_eval(owned == _cfProp); // expected-warning{{TRUE}} 800*67e74705SXin Li} 801*67e74705SXin Li 802*67e74705SXin Li- (void)testPropertyAccessThenReleaseCF2 { 803*67e74705SXin Li CFTypeRef fromIvar = _cfProp; 804*67e74705SXin Li CFTypeRef owned = CFRetain(self.cfProp); 805*67e74705SXin Li CFRelease(owned); 806*67e74705SXin Li CFRelease(fromIvar); 807*67e74705SXin Li clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}} 808*67e74705SXin Li} 809*67e74705SXin Li 810*67e74705SXin Li- (void)testPropertyAccessThenReleaseReadonly { 811*67e74705SXin Li id prop = [self.readonlyProp retain]; 812*67e74705SXin Li [prop release]; 813*67e74705SXin Li [_readonlyProp release]; // no-warning 814*67e74705SXin Li} 815*67e74705SXin Li 816*67e74705SXin Li- (void)testPropertyAccessThenReleaseReadonly2 { 817*67e74705SXin Li id fromIvar = _readonlyProp; 818*67e74705SXin Li id prop = [self.readonlyProp retain]; 819*67e74705SXin Li [prop release]; 820*67e74705SXin Li clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 821*67e74705SXin Li [fromIvar release]; // no-warning 822*67e74705SXin Li} 823*67e74705SXin Li 824*67e74705SXin Li- (void)testPropertyAccessThenReleaseImplicitManual { 825*67e74705SXin Li id prop = [self.implicitManualProp retain]; 826*67e74705SXin Li [prop release]; 827*67e74705SXin Li [_implicitManualProp release]; // no-warning 828*67e74705SXin Li} 829*67e74705SXin Li 830*67e74705SXin Li- (void)testPropertyAccessThenReleaseImplicitManual2 { 831*67e74705SXin Li id fromIvar = _implicitManualProp; 832*67e74705SXin Li id prop = [self.implicitManualProp retain]; 833*67e74705SXin Li [prop release]; 834*67e74705SXin Li clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 835*67e74705SXin Li [fromIvar release]; // no-warning 836*67e74705SXin Li} 837*67e74705SXin Li 838*67e74705SXin Li- (void)testPropertyAccessThenReleaseImplicitSynth { 839*67e74705SXin Li id prop = [self.implicitSynthProp retain]; 840*67e74705SXin Li [prop release]; 841*67e74705SXin Li [_implicitSynthProp release]; // FIXME-warning{{not owned}} 842*67e74705SXin Li} 843*67e74705SXin Li 844*67e74705SXin Li- (void)testPropertyAccessThenReleaseImplicitSynth2 { 845*67e74705SXin Li id fromIvar = _implicitSynthProp; 846*67e74705SXin Li id prop = [self.implicitSynthProp retain]; 847*67e74705SXin Li [prop release]; 848*67e74705SXin Li clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 849*67e74705SXin Li [fromIvar release]; // FIXME-warning{{not owned}} 850*67e74705SXin Li} 851*67e74705SXin Li 852*67e74705SXin Li- (id)getUnownedFromProperty { 853*67e74705SXin Li [_ownedProp retain]; 854*67e74705SXin Li [_ownedProp autorelease]; 855*67e74705SXin Li return _ownedProp; // no-warning 856*67e74705SXin Li} 857*67e74705SXin Li 858*67e74705SXin Li- (id)transferUnownedFromProperty { 859*67e74705SXin Li [_ownedProp retain]; 860*67e74705SXin Li [_ownedProp autorelease]; 861*67e74705SXin Li return [_ownedProp autorelease]; // no-warning 862*67e74705SXin Li} 863*67e74705SXin Li 864*67e74705SXin Li- (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) { 865*67e74705SXin Li [_ownedProp retain]; 866*67e74705SXin Li [_ownedProp autorelease]; 867*67e74705SXin Li return _ownedProp; // no-warning 868*67e74705SXin Li} 869*67e74705SXin Li 870*67e74705SXin Li- (void)testAssignOwned:(id)newValue { 871*67e74705SXin Li _ownedProp = newValue; 872*67e74705SXin Li [_ownedProp release]; // FIXME: no-warning{{not owned}} 873*67e74705SXin Li} 874*67e74705SXin Li 875*67e74705SXin Li- (void)testAssignUnowned:(id)newValue { 876*67e74705SXin Li _unownedProp = newValue; 877*67e74705SXin Li [_unownedProp release]; // FIXME: no-warning{{not owned}} 878*67e74705SXin Li} 879*67e74705SXin Li 880*67e74705SXin Li- (void)testAssignIvarOnly:(id)newValue { 881*67e74705SXin Li _ivarOnly = newValue; 882*67e74705SXin Li [_ivarOnly release]; // FIXME: no-warning{{not owned}} 883*67e74705SXin Li} 884*67e74705SXin Li 885*67e74705SXin Li- (void)testAssignCF:(CFTypeRef)newValue { 886*67e74705SXin Li _cfProp = newValue; 887*67e74705SXin Li CFRelease(_cfProp); // FIXME: no-warning{{not owned}} 888*67e74705SXin Li} 889*67e74705SXin Li 890*67e74705SXin Li- (void)testAssignReadonly:(id)newValue { 891*67e74705SXin Li _readonlyProp = newValue; 892*67e74705SXin Li [_readonlyProp release]; // FIXME: no-warning{{not owned}} 893*67e74705SXin Li} 894*67e74705SXin Li 895*67e74705SXin Li- (void)testAssignImplicitManual:(id)newValue { 896*67e74705SXin Li _implicitManualProp = newValue; 897*67e74705SXin Li [_implicitManualProp release]; // FIXME: no-warning{{not owned}} 898*67e74705SXin Li} 899*67e74705SXin Li 900*67e74705SXin Li- (void)testAssignImplicitSynth:(id)newValue { 901*67e74705SXin Li _implicitSynthProp = newValue; 902*67e74705SXin Li [_implicitSynthProp release]; // FIXME: no-warning{{not owned}} 903*67e74705SXin Li} 904*67e74705SXin Li 905*67e74705SXin Li- (void)testAssignOwnedOkay:(id)newValue { 906*67e74705SXin Li _ownedProp = [newValue retain]; 907*67e74705SXin Li [_ownedProp release]; // no-warning 908*67e74705SXin Li} 909*67e74705SXin Li 910*67e74705SXin Li- (void)testAssignUnownedOkay:(id)newValue { 911*67e74705SXin Li _unownedProp = [newValue retain]; 912*67e74705SXin Li [_unownedProp release]; // no-warning 913*67e74705SXin Li} 914*67e74705SXin Li 915*67e74705SXin Li- (void)testAssignIvarOnlyOkay:(id)newValue { 916*67e74705SXin Li _ivarOnly = [newValue retain]; 917*67e74705SXin Li [_ivarOnly release]; // no-warning 918*67e74705SXin Li} 919*67e74705SXin Li 920*67e74705SXin Li- (void)testAssignCFOkay:(CFTypeRef)newValue { 921*67e74705SXin Li _cfProp = CFRetain(newValue); 922*67e74705SXin Li CFRelease(_cfProp); // no-warning 923*67e74705SXin Li} 924*67e74705SXin Li 925*67e74705SXin Li- (void)testAssignReadonlyOkay:(id)newValue { 926*67e74705SXin Li _readonlyProp = [newValue retain]; 927*67e74705SXin Li [_readonlyProp release]; // FIXME: no-warning{{not owned}} 928*67e74705SXin Li} 929*67e74705SXin Li 930*67e74705SXin Li- (void)testAssignImplicitManualOkay:(id)newValue { 931*67e74705SXin Li _implicitManualProp = [newValue retain]; 932*67e74705SXin Li [_implicitManualProp release]; // FIXME: no-warning{{not owned}} 933*67e74705SXin Li} 934*67e74705SXin Li 935*67e74705SXin Li- (void)testAssignImplicitSynthOkay:(id)newValue { 936*67e74705SXin Li _implicitSynthProp = [newValue retain]; 937*67e74705SXin Li [_implicitSynthProp release]; // FIXME: no-warning{{not owned}} 938*67e74705SXin Li} 939*67e74705SXin Li 940*67e74705SXin Li// rdar://problem/19862648 941*67e74705SXin Li- (void)establishIvarIsNilDuringLoops { 942*67e74705SXin Li extern id getRandomObject(); 943*67e74705SXin Li 944*67e74705SXin Li int i = 4; // Must be at least 4 to trigger the bug. 945*67e74705SXin Li while (--i) { 946*67e74705SXin Li id x = 0; 947*67e74705SXin Li if (getRandomObject()) 948*67e74705SXin Li x = _ivarOnly; 949*67e74705SXin Li if (!x) 950*67e74705SXin Li x = getRandomObject(); 951*67e74705SXin Li [x myMethod]; 952*67e74705SXin Li } 953*67e74705SXin Li} 954*67e74705SXin Li 955*67e74705SXin Li// rdar://problem/20335433 956*67e74705SXin Li- (void)retainIvarAndInvalidateSelf { 957*67e74705SXin Li extern void invalidate(id); 958*67e74705SXin Li [_unownedProp retain]; 959*67e74705SXin Li invalidate(self); 960*67e74705SXin Li [_unownedProp release]; // no-warning 961*67e74705SXin Li} 962*67e74705SXin Li 963*67e74705SXin Li@end 964*67e74705SXin Li#endif // non-ARC 965*67e74705SXin Li 966