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