1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s 2// RUN: %clang_analyze_cc1 -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__attribute__((objc_root_class)) 319@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory 320@end 321 322@protocol HasStuff 323@property (nonatomic, readonly) int stuffProperty; 324@end 325 326@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private) 327@property (nonatomic, readonly) int stuffProperty; 328@end 329 330@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff> 331@end 332 333@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff> 334@end 335 336@implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory 337@synthesize stuffProperty = _stuffProperty; 338 339-(void)foo { 340 (void)self.stuffProperty; 341} 342@end 343 344//------ 345// Setter ivar invalidation. 346//------ 347 348@interface ClassWithSetters 349// Note: These properties have implicit @synthesize implementations to be 350// backed with ivars. 351@property (assign) int propWithIvar1; 352@property (assign) int propWithIvar2; 353 354@property (retain) NSNumber *retainedProperty; 355 356@end 357 358@interface ClassWithSetters (InOtherTranslationUnit) 359// The implementation of this property is in another translation unit. 360// We don't know whether it is backed by an ivar or not. 361@property (assign) int propInOther; 362@end 363 364@implementation ClassWithSetters 365- (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; { 366 _propWithIvar1 = 1; 367 _propWithIvar2 = 2; 368 self.propWithIvar1 = 66; 369 370 // Calling the setter of a property backed by the instance variable 371 // should invalidate the storage for the instance variable but not 372 // the rest of the receiver. Ideally we would model the setter completely 373 // but doing so would cause the new value to escape when it is bound 374 // to the ivar. This would cause bad false negatives in the retain count 375 // checker. (There is a test for this scenario in 376 // testWriteRetainedValueToRetainedProperty below). 377 clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 378 clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{TRUE}} 379 380 _propWithIvar1 = 1; 381 [self setPropWithIvar1:66]; 382 383 clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 384 clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{TRUE}} 385} 386 387- (void) testSettingPropWithoutIvarInvalidatesEntireInstance; { 388 _propWithIvar1 = 1; 389 _propWithIvar2 = 2; 390 self.propInOther = 66; 391 392 clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 393 clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{UNKNOWN}} 394 395 _propWithIvar1 = 1; 396 _propWithIvar2 = 2; 397 [self setPropInOther:66]; 398 399 clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}} 400 clang_analyzer_eval(_propWithIvar2 == 2); // expected-warning{{UNKNOWN}} 401} 402 403#if !__has_feature(objc_arc) 404- (void) testWriteRetainedValueToRetainedProperty; { 405 NSNumber *number = [[NSNumber alloc] initWithInteger:5]; // expected-warning {{Potential leak of an object stored into 'number'}} 406 407 // Make sure we catch this leak. 408 self.retainedProperty = number; 409} 410#endif 411@end 412 413//------ 414// class properties 415//------ 416 417int gBackingForReadWriteClassProp = 0; 418 419@interface ClassWithClassProperties 420@property(class, readonly) int readOnlyClassProp; 421 422@property(class) int readWriteClassProp; 423 424// Make sure we handle when a class and instance property have the same 425// name. Test both when instance comes first and when class comes first. 426@property(readonly) int classAndInstancePropWithSameNameOrderInstanceFirst; 427@property(class, readonly) int classAndInstancePropWithSameNameOrderInstanceFirst; 428 429@property(class, readonly) int classAndInstancePropWithSameNameOrderClassFirst; 430@property(readonly) int classAndInstancePropWithSameNameOrderClassFirst; 431 432 433@property(class, readonly) int dynamicClassProp; 434 435@end 436 437@interface ClassWithClassProperties (OtherTranslationUnit) 438@property(class, assign) id propInOtherTranslationUnit; 439@end 440 441@implementation ClassWithClassProperties 442 443@dynamic dynamicClassProp; 444 445+ (int)readOnlyClassProp { 446 return 1; 447} 448 449+ (int)readWriteClassProp { 450 return gBackingForReadWriteClassProp; 451} 452 453+ (void)setReadWriteClassProp:(int)val { 454 gBackingForReadWriteClassProp = val; 455} 456 457- (int)classAndInstancePropWithSameNameOrderInstanceFirst { 458 return 12; 459} 460 461+ (int)classAndInstancePropWithSameNameOrderInstanceFirst { 462 return 13; 463} 464 465+ (int)classAndInstancePropWithSameNameOrderClassFirst { 466 return 14; 467} 468 469- (int)classAndInstancePropWithSameNameOrderClassFirst { 470 return 15; 471} 472 473- (void)testInlineClassProp { 474 clang_analyzer_eval(ClassWithClassProperties.readOnlyClassProp == 1); // expected-warning{{TRUE}} 475 476 ClassWithClassProperties.readWriteClassProp = 7; 477 clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 7); // expected-warning{{TRUE}} 478 ClassWithClassProperties.readWriteClassProp = 8; 479 clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 8); // expected-warning{{TRUE}} 480} 481 482- (void)testUnknownClassProp { 483 clang_analyzer_eval(ClassWithClassProperties.propInOtherTranslationUnit == ClassWithClassProperties.propInOtherTranslationUnit); // expected-warning{{UNKNOWN}} 484} 485 486- (void)testEscapeGlobalOnUnknownProp { 487 gBackingForReadWriteClassProp = 33; 488 ClassWithClassProperties.propInOtherTranslationUnit = 0; 489 clang_analyzer_eval(gBackingForReadWriteClassProp == 33); // expected-warning{{UNKNOWN}} 490} 491 492- (void)testClassAndInstancePropertyWithSameName { 493 clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderInstanceFirst == 12); // expected-warning{{TRUE}} 494 clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderInstanceFirst == 13); // expected-warning{{TRUE}} 495 496 clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderClassFirst == 14); // expected-warning{{TRUE}} 497 clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderClassFirst == 15); // expected-warning{{TRUE}} 498} 499 500- (void)testDynamicClassProp { 501 clang_analyzer_eval(ClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{UNKNOWN}} 502} 503 504@end 505 506@interface SubclassOfClassWithClassProperties : ClassWithClassProperties 507@end 508 509@implementation SubclassOfClassWithClassProperties 510+ (int)dynamicClassProp; { 511 return 16; 512} 513 514- (void)testDynamicClassProp { 515 clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}} 516} 517 518@end 519 520 521#if !__has_feature(objc_arc) 522void testOverrelease(Person *p, int coin) { 523 switch (coin) { 524 case 0: 525 [p.name release]; // expected-warning{{not owned}} 526 break; 527 case 1: 528 [p.friend release]; // expected-warning{{not owned}} 529 break; 530 case 2: { 531 id friend = p.friend; 532 doSomethingWithPerson(p); 533 [friend release]; // expected-warning{{not owned}} 534 } 535 } 536} 537 538// <rdar://problem/16333368> 539@implementation Person (Rdar16333368) 540 541- (void)testDeliberateRelease:(Person *)other { 542 doSomethingWithName(self.name); 543 [_name release]; // no-warning 544 self->_name = 0; 545 546 doSomethingWithName(other->_name); 547 [other.name release]; // no-warning 548} 549 550- (void)deliberateReleaseFalseNegative { 551 // This is arguably a false negative because the result of p.friend shouldn't 552 // be released, even though we are manipulating the ivar in between the two 553 // actions. 554 id name = self.name; 555 _name = 0; 556 [name release]; 557} 558 559- (void)testRetainAndRelease { 560 [self.name retain]; 561 [self.name release]; 562 [self.name release]; // expected-warning{{not owned}} 563} 564 565- (void)testRetainAndReleaseIVar { 566 [self.name retain]; 567 [_name release]; 568 [_name release]; 569} 570 571@end 572#endif 573 574@interface IntWrapper 575@property int value; 576@end 577 578@implementation IntWrapper 579@synthesize value; 580@end 581 582void testConsistencyInt(IntWrapper *w) { 583 clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}} 584 585 int origValue = w.value; 586 if (origValue != 42) 587 return; 588 589 clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 590} 591 592void testConsistencyInt2(IntWrapper *w) { 593 if (w.value != 42) 594 return; 595 596 clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 597} 598 599 600@interface IntWrapperAuto 601@property int value; 602@end 603 604@implementation IntWrapperAuto 605@end 606 607void testConsistencyIntAuto(IntWrapperAuto *w) { 608 clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}} 609 610 int origValue = w.value; 611 if (origValue != 42) 612 return; 613 614 clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 615} 616 617void testConsistencyIntAuto2(IntWrapperAuto *w) { 618 if (w.value != 42) 619 return; 620 621 clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}} 622} 623 624 625typedef struct { 626 int value; 627} IntWrapperStruct; 628 629@interface StructWrapper 630@property IntWrapperStruct inner; 631@end 632 633@implementation StructWrapper 634@synthesize inner; 635@end 636 637void testConsistencyStruct(StructWrapper *w) { 638 clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}} 639 640 int origValue = w.inner.value; 641 if (origValue != 42) 642 return; 643 644 clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}} 645} 646 647 648@interface OpaqueIntWrapper 649@property int value; 650@end 651 652// For now, don't assume a property is implemented using an ivar unless we can 653// actually see that it is. 654void testOpaqueConsistency(OpaqueIntWrapper *w) { 655 clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}} 656} 657 658 659#if !__has_feature(objc_arc) 660// Test quite a few cases of retain/release issues. 661 662@interface RetainCountTesting 663@property (strong) id ownedProp; 664@property (unsafe_unretained) id unownedProp; 665@property (nonatomic, strong) id manualProp; 666@property (readonly) id readonlyProp; 667@property (nonatomic, readwrite/*, assign */) id implicitManualProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}} 668@property (nonatomic, readwrite/*, assign */) id implicitSynthProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}} 669@property CFTypeRef cfProp; 670@end 671 672@implementation RetainCountTesting { 673 id _ivarOnly; 674} 675 676- (id)manualProp { 677 return _manualProp; 678} 679 680- (void)setImplicitManualProp:(id)newValue {} 681 682- (void)testOverreleaseOwnedIvar { 683 [_ownedProp retain]; 684 [_ownedProp release]; 685 [_ownedProp release]; 686 [_ownedProp release]; // FIXME-warning{{used after it is released}} 687} 688 689- (void)testOverreleaseUnownedIvar { 690 [_unownedProp retain]; 691 [_unownedProp release]; 692 [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}} 693} 694 695- (void)testOverreleaseIvarOnly { 696 [_ivarOnly retain]; 697 [_ivarOnly release]; 698 [_ivarOnly release]; 699 [_ivarOnly release]; // FIXME-warning{{used after it is released}} 700} 701 702- (void)testOverreleaseReadonlyIvar { 703 [_readonlyProp retain]; 704 [_readonlyProp release]; 705 [_readonlyProp release]; 706 [_readonlyProp release]; // FIXME-warning{{used after it is released}} 707} 708 709- (void)testOverreleaseImplicitManualIvar { 710 [_implicitManualProp retain]; 711 [_implicitManualProp release]; 712 [_implicitManualProp release]; 713 [_implicitManualProp release]; // FIXME-warning{{used after it is released}} 714} 715 716- (void)testOverreleaseImplicitSynthIvar { 717 [_implicitSynthProp retain]; 718 [_implicitSynthProp release]; 719 [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}} 720} 721 722- (void)testOverreleaseCF { 723 CFRetain(_cfProp); 724 CFRelease(_cfProp); 725 CFRelease(_cfProp); 726 CFRelease(_cfProp); // FIXME-warning{{used after it is released}} 727} 728 729- (void)testOverreleaseOwnedIvarUse { 730 [_ownedProp retain]; 731 [_ownedProp release]; 732 [_ownedProp release]; 733 [_ownedProp myMethod]; // FIXME-warning{{used after it is released}} 734} 735 736- (void)testOverreleaseIvarOnlyUse { 737 [_ivarOnly retain]; 738 [_ivarOnly release]; 739 [_ivarOnly release]; 740 [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}} 741} 742 743- (void)testOverreleaseCFUse { 744 CFRetain(_cfProp); 745 CFRelease(_cfProp); 746 CFRelease(_cfProp); 747 748 extern void CFUse(CFTypeRef); 749 CFUse(_cfProp); // FIXME-warning{{used after it is released}} 750} 751 752- (void)testOverreleaseOwnedIvarAutoreleaseOkay { 753 [_ownedProp retain]; 754 [_ownedProp release]; 755 [_ownedProp autorelease]; 756} // no-warning 757 758- (void)testOverreleaseIvarOnlyAutoreleaseOkay { 759 [_ivarOnly retain]; 760 [_ivarOnly release]; 761 [_ivarOnly autorelease]; 762} // no-warning 763 764- (void)testOverreleaseOwnedIvarAutorelease { 765 [_ownedProp retain]; 766 [_ownedProp release]; 767 [_ownedProp autorelease]; 768 [_ownedProp autorelease]; 769} // FIXME-warning{{Object autoreleased too many times}} 770 771- (void)testOverreleaseIvarOnlyAutorelease { 772 [_ivarOnly retain]; 773 [_ivarOnly release]; 774 [_ivarOnly autorelease]; 775 [_ivarOnly autorelease]; 776} // FIXME-warning{{Object autoreleased too many times}} 777 778- (void)testPropertyAccessThenReleaseOwned { 779 id owned = [self.ownedProp retain]; 780 [owned release]; 781 [_ownedProp release]; 782 clang_analyzer_eval(owned == _ownedProp); // expected-warning{{TRUE}} 783} 784 785- (void)testPropertyAccessThenReleaseOwned2 { 786 id fromIvar = _ownedProp; 787 id owned = [self.ownedProp retain]; 788 [owned release]; 789 [fromIvar release]; 790 clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}} 791} 792 793- (void)testPropertyAccessThenReleaseUnowned { 794 id unowned = [self.unownedProp retain]; 795 [unowned release]; 796 [_unownedProp release]; // FIXME-warning{{not owned}} 797} 798 799- (void)testPropertyAccessThenReleaseUnowned2 { 800 id fromIvar = _unownedProp; 801 id unowned = [self.unownedProp retain]; 802 [unowned release]; 803 clang_analyzer_eval(unowned == fromIvar); // expected-warning{{TRUE}} 804 [fromIvar release]; // FIXME-warning{{not owned}} 805} 806 807- (void)testPropertyAccessThenReleaseManual { 808 id prop = [self.manualProp retain]; 809 [prop release]; 810 [_manualProp release]; // no-warning 811} 812 813- (void)testPropertyAccessThenReleaseManual2 { 814 id fromIvar = _manualProp; 815 id prop = [self.manualProp retain]; 816 [prop release]; 817 clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 818 [fromIvar release]; // no-warning 819} 820 821- (void)testPropertyAccessThenReleaseCF { 822 CFTypeRef owned = CFRetain(self.cfProp); 823 CFRelease(owned); 824 CFRelease(_cfProp); // no-warning 825 clang_analyzer_eval(owned == _cfProp); // expected-warning{{TRUE}} 826} 827 828- (void)testPropertyAccessThenReleaseCF2 { 829 CFTypeRef fromIvar = _cfProp; 830 CFTypeRef owned = CFRetain(self.cfProp); 831 CFRelease(owned); 832 CFRelease(fromIvar); 833 clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}} 834} 835 836- (void)testPropertyAccessThenReleaseReadonly { 837 id prop = [self.readonlyProp retain]; 838 [prop release]; 839 [_readonlyProp release]; // no-warning 840} 841 842- (void)testPropertyAccessThenReleaseReadonly2 { 843 id fromIvar = _readonlyProp; 844 id prop = [self.readonlyProp retain]; 845 [prop release]; 846 clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 847 [fromIvar release]; // no-warning 848} 849 850- (void)testPropertyAccessThenReleaseImplicitManual { 851 id prop = [self.implicitManualProp retain]; 852 [prop release]; 853 [_implicitManualProp release]; // no-warning 854} 855 856- (void)testPropertyAccessThenReleaseImplicitManual2 { 857 id fromIvar = _implicitManualProp; 858 id prop = [self.implicitManualProp retain]; 859 [prop release]; 860 clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 861 [fromIvar release]; // no-warning 862} 863 864- (void)testPropertyAccessThenReleaseImplicitSynth { 865 id prop = [self.implicitSynthProp retain]; 866 [prop release]; 867 [_implicitSynthProp release]; // FIXME-warning{{not owned}} 868} 869 870- (void)testPropertyAccessThenReleaseImplicitSynth2 { 871 id fromIvar = _implicitSynthProp; 872 id prop = [self.implicitSynthProp retain]; 873 [prop release]; 874 clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}} 875 [fromIvar release]; // FIXME-warning{{not owned}} 876} 877 878- (id)getUnownedFromProperty { 879 [_ownedProp retain]; 880 [_ownedProp autorelease]; 881 return _ownedProp; // no-warning 882} 883 884- (id)transferUnownedFromProperty { 885 [_ownedProp retain]; 886 [_ownedProp autorelease]; 887 return [_ownedProp autorelease]; // no-warning 888} 889 890- (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) { 891 [_ownedProp retain]; 892 [_ownedProp autorelease]; 893 return _ownedProp; // no-warning 894} 895 896- (void)testAssignOwned:(id)newValue { 897 _ownedProp = newValue; 898 [_ownedProp release]; // FIXME: no-warning{{not owned}} 899} 900 901- (void)testAssignUnowned:(id)newValue { 902 _unownedProp = newValue; 903 [_unownedProp release]; // FIXME: no-warning{{not owned}} 904} 905 906- (void)testAssignIvarOnly:(id)newValue { 907 _ivarOnly = newValue; 908 [_ivarOnly release]; // FIXME: no-warning{{not owned}} 909} 910 911- (void)testAssignCF:(CFTypeRef)newValue { 912 _cfProp = newValue; 913 CFRelease(_cfProp); // FIXME: no-warning{{not owned}} 914} 915 916- (void)testAssignReadonly:(id)newValue { 917 _readonlyProp = newValue; 918 [_readonlyProp release]; // FIXME: no-warning{{not owned}} 919} 920 921- (void)testAssignImplicitManual:(id)newValue { 922 _implicitManualProp = newValue; 923 [_implicitManualProp release]; // FIXME: no-warning{{not owned}} 924} 925 926- (void)testAssignImplicitSynth:(id)newValue { 927 _implicitSynthProp = newValue; 928 [_implicitSynthProp release]; // FIXME: no-warning{{not owned}} 929} 930 931- (void)testAssignOwnedOkay:(id)newValue { 932 _ownedProp = [newValue retain]; 933 [_ownedProp release]; // no-warning 934} 935 936- (void)testAssignUnownedOkay:(id)newValue { 937 _unownedProp = [newValue retain]; 938 [_unownedProp release]; // no-warning 939} 940 941- (void)testAssignIvarOnlyOkay:(id)newValue { 942 _ivarOnly = [newValue retain]; 943 [_ivarOnly release]; // no-warning 944} 945 946- (void)testAssignCFOkay:(CFTypeRef)newValue { 947 _cfProp = CFRetain(newValue); 948 CFRelease(_cfProp); // no-warning 949} 950 951- (void)testAssignReadonlyOkay:(id)newValue { 952 _readonlyProp = [newValue retain]; 953 [_readonlyProp release]; // FIXME: no-warning{{not owned}} 954} 955 956- (void)testAssignImplicitManualOkay:(id)newValue { 957 _implicitManualProp = [newValue retain]; 958 [_implicitManualProp release]; // FIXME: no-warning{{not owned}} 959} 960 961- (void)testAssignImplicitSynthOkay:(id)newValue { 962 _implicitSynthProp = [newValue retain]; 963 [_implicitSynthProp release]; // FIXME: no-warning{{not owned}} 964} 965 966// rdar://problem/19862648 967- (void)establishIvarIsNilDuringLoops { 968 extern id getRandomObject(); 969 970 int i = 4; // Must be at least 4 to trigger the bug. 971 while (--i) { 972 id x = 0; 973 if (getRandomObject()) 974 x = _ivarOnly; 975 if (!x) 976 x = getRandomObject(); 977 [x myMethod]; 978 } 979} 980 981// rdar://problem/20335433 982- (void)retainIvarAndInvalidateSelf { 983 extern void invalidate(id); 984 [_unownedProp retain]; 985 invalidate(self); 986 [_unownedProp release]; // no-warning 987} 988 989@end 990 991@interface Wrapper 992@property(nonatomic, readonly) int value; 993@end 994 995@implementation Wrapper 996@synthesize value; 997@end 998 999void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll() { 1000 union { 1001 Wrapper *wrapper; 1002 } u = { 0 }; 1003 [u.wrapper value]; 1004} 1005 1006#endif // non-ARC 1007 1008