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