[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / properties.m
blobb12af2fadd66aa45a43d49b66199c9ecc45e37d2
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -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 -verify -Wno-objc-root-class -fobjc-arc -analyzer-config eagerly-assume=false %s
4 void clang_analyzer_eval(int);
6 #define nil ((id)0)
8 typedef const void * CFTypeRef;
9 extern CFTypeRef CFRetain(CFTypeRef cf);
10 void CFRelease(CFTypeRef cf);
12 typedef signed char BOOL;
13 typedef unsigned int NSUInteger;
14 typedef 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
40 // rdar://6946338
42 @interface Test1 : NSObject {
43   NSString *text;
45 -(id)myMethod;
46 @property (nonatomic, assign) NSString *text;
47 @end
50 #if !__has_feature(objc_arc)
52 @implementation Test1
54 @synthesize text;
56 -(id)myMethod {
57   Test1 *cell = [[[Test1 alloc] init] autorelease];
59   NSString *string1 = [[NSString alloc] initWithFormat:@"test %f", 0.0]; // expected-warning {{Potential leak}}
60   cell.text = string1;
62   return cell;
65 @end
68 // rdar://8824416
70 @interface MyNumber : NSObject
72   NSNumber* _myNumber;
75 - (id)initWithNumber:(NSNumber *)number;
77 @property (nonatomic, readonly) NSNumber* myNumber;
78 @property (nonatomic, readonly) NSNumber* newMyNumber;
80 @end
82 @implementation MyNumber
83 @synthesize myNumber=_myNumber;
85 - (id)initWithNumber:(NSNumber *)number
87   self = [super init];
88   
89   if ( self )
90   {
91     _myNumber = [number copy];
92   }
93   
94   return self;
97 - (NSNumber*)newMyNumber
99   if ( _myNumber )
100     return [_myNumber retain];
101   
102   return [[NSNumber alloc] initWithInteger:1];
105 - (id)valueForUndefinedKey:(NSString*)key
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}}
121 @end
123 NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
125   NSNumber* result = aMyNumber.myNumber;
126     
127   return [result autorelease]; // expected-warning {{Object autoreleased too many times}}
130 #endif
133 // rdar://6611873
135 @interface Person : NSObject {
136   NSString *_name;
138 @property (retain) NSString * name;
139 @property (assign) id friend;
140 @end
142 @implementation Person
143 @synthesize name = _name;
145 -(void)dealloc {
146 #if !__has_feature(objc_arc)
147   self.name = [[NSString alloc] init]; // expected-warning {{leak}}
149   [super dealloc]; // expected-warning {{The '_name' ivar in 'Person' was retained by a synthesized property but not released before '[super dealloc]}}
150 #endif
152 @end
154 #if !__has_feature(objc_arc)
155 void rdar6611873(void) {
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}}
161   p.friend = [[Person alloc] init]; // expected-warning {{leak}}
163 #endif
165 @interface SubPerson : Person
166 -(NSString *)foo;
167 @end
169 @implementation SubPerson
170 -(NSString *)foo {
171   return super.name;
173 @end
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
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}}
192 -(void)testAnalyzer2 {
193   id y;
194   self.x = y;  // expected-warning {{Argument for property setter is an uninitialized value}}
196 @end
197 #endif
200 //------
201 // Property accessor synthesis
202 //------
204 extern void doSomethingWithPerson(Person *p);
205 extern void doSomethingWithName(NSString *name);
207 void testConsistencyRetain(Person *p) {
208   clang_analyzer_eval(p.name == p.name); // expected-warning{{TRUE}}
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}}
216 void testConsistencyAssign(Person *p) {
217   clang_analyzer_eval(p.friend == p.friend); // expected-warning{{TRUE}}
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}}
225 @interface ClassWithShadowedReadWriteProperty {
226   int _f;
228 @property (readonly) int someProp;
229 @end
231 @interface ClassWithShadowedReadWriteProperty ()
232 @property (readwrite) int someProp;
233 @end
235 @implementation ClassWithShadowedReadWriteProperty
236 - (void)testSynthesisForShadowedReadWriteProperties; {
237   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
239   _f = 1;
241   // Read of shadowed property should not invalidate receiver.
242   (void)self.someProp;
243   clang_analyzer_eval(_f == 1); // expected-warning{{TRUE}}
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}}
250 @end
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
259 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
260 @end
262 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
263 @property (readwrite) int someProp;
264 @property (readonly) int otherProp;
265 @end
267 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory (MyCat)
268 @property (readonly) int someProp;
269 @property (readonly) int otherProp;
270 @end
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}}
277   clang_analyzer_eval(self.otherProp == self.otherProp); // expected-warning{{TRUE}}
278   clang_analyzer_eval([self otherProp] == self.otherProp); // expected-warning{{TRUE}}
280 @end
282 // The relative order of the extension and the category matter, so test both.
283 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension
284 @end
286 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension ()
287 @property (readwrite) int someProp;
288 @end
290 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension (MyCat)
291 @property (readonly) int someProp;
292 @end
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}}
299 @end
301 @interface ClassWithSynthesizedPropertyAndGetter
302 @property (readonly) int someProp;
303 @end
305 @implementation ClassWithSynthesizedPropertyAndGetter
306 @synthesize someProp;
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}}
315 -(int)someProp {
316   return 22;
318 @end
320 __attribute__((objc_root_class))
321 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
322 @end
324 @protocol HasStuff
325 @property (nonatomic, readonly) int stuffProperty;
326 @end
328 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private)
329 @property (nonatomic, readonly) int stuffProperty;
330 @end
332 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff>
333 @end
335 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff>
336 @end
338 @implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
339 @synthesize stuffProperty = _stuffProperty;
341 -(void)foo {
342   (void)self.stuffProperty;
344 @end
346 //------
347 // Setter ivar invalidation.
348 //------
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;
356 @property (retain) NSNumber *retainedProperty;
358 @end
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
366 @implementation ClassWithSetters
367 - (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; {
368   _propWithIvar1 = 1;
369   _propWithIvar2 = 2;
370   self.propWithIvar1 = 66;
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}}
382   _propWithIvar1 = 1;
383   [self setPropWithIvar1:66];
385   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
386   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}
389 - (void) testSettingPropWithoutIvarInvalidatesEntireInstance; {
390   _propWithIvar1 = 1;
391   _propWithIvar2 = 2;
392   self.propInOther = 66;
394   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
395   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
397   _propWithIvar1 = 1;
398   _propWithIvar2 = 2;
399   [self setPropInOther:66];
401   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
402   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
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'}}
409   // Make sure we catch this leak.
410   self.retainedProperty = number;
412 #endif
413 @end
415 //------
416 // class properties
417 //------
419 int gBackingForReadWriteClassProp = 0;
421 @interface ClassWithClassProperties
422 @property(class, readonly) int readOnlyClassProp;
424 @property(class) int readWriteClassProp;
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;
431 @property(class, readonly) int classAndInstancePropWithSameNameOrderClassFirst;
432 @property(readonly) int classAndInstancePropWithSameNameOrderClassFirst;
435 @property(class, readonly) int dynamicClassProp;
437 @end
439 @interface ClassWithClassProperties (OtherTranslationUnit)
440 @property(class, assign) id propInOtherTranslationUnit;
441 @end
443 @implementation ClassWithClassProperties
445 @dynamic dynamicClassProp;
447 + (int)readOnlyClassProp {
448   return 1;
451 + (int)readWriteClassProp {
452   return gBackingForReadWriteClassProp;
455 + (void)setReadWriteClassProp:(int)val {
456   gBackingForReadWriteClassProp = val;
459 - (int)classAndInstancePropWithSameNameOrderInstanceFirst {
460   return 12;
463 + (int)classAndInstancePropWithSameNameOrderInstanceFirst {
464   return 13;
467 + (int)classAndInstancePropWithSameNameOrderClassFirst {
468   return 14;
471 - (int)classAndInstancePropWithSameNameOrderClassFirst {
472   return 15;
475 - (void)testInlineClassProp {
476   clang_analyzer_eval(ClassWithClassProperties.readOnlyClassProp == 1); // expected-warning{{TRUE}}
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}}
484 - (void)testUnknownClassProp {
485   clang_analyzer_eval(ClassWithClassProperties.propInOtherTranslationUnit == ClassWithClassProperties.propInOtherTranslationUnit); // expected-warning{{UNKNOWN}}
488 - (void)testEscapeGlobalOnUnknownProp {
489   gBackingForReadWriteClassProp = 33;
490   ClassWithClassProperties.propInOtherTranslationUnit = 0;
491   clang_analyzer_eval(gBackingForReadWriteClassProp == 33); // expected-warning{{UNKNOWN}}
494 - (void)testClassAndInstancePropertyWithSameName {
495   clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderInstanceFirst == 12); // expected-warning{{TRUE}}
496   clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderInstanceFirst == 13); // expected-warning{{TRUE}}
498   clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderClassFirst == 14); // expected-warning{{TRUE}}
499   clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderClassFirst == 15); // expected-warning{{TRUE}}
502 - (void)testDynamicClassProp {
503   clang_analyzer_eval(ClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{UNKNOWN}}
506 @end
508 @interface SubclassOfClassWithClassProperties : ClassWithClassProperties
509 @end
511 @implementation SubclassOfClassWithClassProperties
512 + (int)dynamicClassProp; {
513  return 16;
516 - (void)testDynamicClassProp {
517   clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}}
520 @end
523 #if !__has_feature(objc_arc)
524 void 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   }
540 // <rdar://problem/16333368>
541 @implementation Person (Rdar16333368)
543 - (void)testDeliberateRelease:(Person *)other {
544   doSomethingWithName(self.name);
545   [_name release]; // no-warning
546   self->_name = 0;
548   doSomethingWithName(other->_name);
549   [other.name release]; // no-warning
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];
561 - (void)testRetainAndRelease {
562   [self.name retain];
563   [self.name release];
564   [self.name release]; // expected-warning{{not owned}}
567 - (void)testRetainAndReleaseIVar {
568   [self.name retain];
569   [_name release];
570   [_name release];
573 @end
574 #endif
576 @interface IntWrapper
577 @property int value;
578 @end
580 @implementation IntWrapper
581 @synthesize value;
582 @end
584 void testConsistencyInt(IntWrapper *w) {
585   clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
587   int origValue = w.value;
588   if (origValue != 42)
589     return;
591   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
594 void testConsistencyInt2(IntWrapper *w) {
595   if (w.value != 42)
596     return;
598   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
602 @interface IntWrapperAuto
603 @property int value;
604 @end
606 @implementation IntWrapperAuto
607 @end
609 void testConsistencyIntAuto(IntWrapperAuto *w) {
610   clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
612   int origValue = w.value;
613   if (origValue != 42)
614     return;
616   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
619 void testConsistencyIntAuto2(IntWrapperAuto *w) {
620   if (w.value != 42)
621     return;
623   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
627 typedef struct {
628   int value;
629 } IntWrapperStruct;
631 @interface StructWrapper
632 @property IntWrapperStruct inner;
633 @end
635 @implementation StructWrapper
636 @synthesize inner;
637 @end
639 void testConsistencyStruct(StructWrapper *w) {
640   clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}
642   int origValue = w.inner.value;
643   if (origValue != 42)
644     return;
646   clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
650 @interface OpaqueIntWrapper
651 @property int value;
652 @end
654 // For now, don't assume a property is implemented using an ivar unless we can
655 // actually see that it is.
656 void testOpaqueConsistency(OpaqueIntWrapper *w) {
657   clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}}
661 #if !__has_feature(objc_arc)
662 // Test quite a few cases of retain/release issues.
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
674 @implementation RetainCountTesting {
675   id _ivarOnly;
678 - (id)manualProp {
679   return _manualProp;
682 - (void)setImplicitManualProp:(id)newValue {}
684 - (void)testOverreleaseOwnedIvar {
685   [_ownedProp retain];
686   [_ownedProp release];
687   [_ownedProp release];
688   [_ownedProp release]; // FIXME-warning{{used after it is released}}
691 - (void)testOverreleaseUnownedIvar {
692   [_unownedProp retain];
693   [_unownedProp release];
694   [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}}
697 - (void)testOverreleaseIvarOnly {
698   [_ivarOnly retain];
699   [_ivarOnly release];
700   [_ivarOnly release];
701   [_ivarOnly release]; // FIXME-warning{{used after it is released}}
704 - (void)testOverreleaseReadonlyIvar {
705   [_readonlyProp retain];
706   [_readonlyProp release];
707   [_readonlyProp release];
708   [_readonlyProp release]; // FIXME-warning{{used after it is released}}
711 - (void)testOverreleaseImplicitManualIvar {
712   [_implicitManualProp retain];
713   [_implicitManualProp release];
714   [_implicitManualProp release];
715   [_implicitManualProp release]; // FIXME-warning{{used after it is released}}
718 - (void)testOverreleaseImplicitSynthIvar {
719   [_implicitSynthProp retain];
720   [_implicitSynthProp release];
721   [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}}
724 - (void)testOverreleaseCF {
725   CFRetain(_cfProp);
726   CFRelease(_cfProp);
727   CFRelease(_cfProp);
728   CFRelease(_cfProp); // FIXME-warning{{used after it is released}}
731 - (void)testOverreleaseOwnedIvarUse {
732   [_ownedProp retain];
733   [_ownedProp release];
734   [_ownedProp release];
735   [_ownedProp myMethod]; // FIXME-warning{{used after it is released}}
738 - (void)testOverreleaseIvarOnlyUse {
739   [_ivarOnly retain];
740   [_ivarOnly release];
741   [_ivarOnly release];
742   [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}}
745 - (void)testOverreleaseCFUse {
746   CFRetain(_cfProp);
747   CFRelease(_cfProp);
748   CFRelease(_cfProp);
750   extern void CFUse(CFTypeRef);
751   CFUse(_cfProp); // FIXME-warning{{used after it is released}}
754 - (void)testOverreleaseOwnedIvarAutoreleaseOkay {
755   [_ownedProp retain];
756   [_ownedProp release];
757   [_ownedProp autorelease];
758 } // no-warning
760 - (void)testOverreleaseIvarOnlyAutoreleaseOkay {
761   [_ivarOnly retain];
762   [_ivarOnly release];
763   [_ivarOnly autorelease];
764 } // no-warning
766 - (void)testOverreleaseOwnedIvarAutorelease {
767   [_ownedProp retain];
768   [_ownedProp release];
769   [_ownedProp autorelease];
770   [_ownedProp autorelease];
771 } // FIXME-warning{{Object autoreleased too many times}}
773 - (void)testOverreleaseIvarOnlyAutorelease {
774   [_ivarOnly retain];
775   [_ivarOnly release];
776   [_ivarOnly autorelease];
777   [_ivarOnly autorelease];
778 } // FIXME-warning{{Object autoreleased too many times}}
780 - (void)testPropertyAccessThenReleaseOwned {
781   id owned = [self.ownedProp retain];
782   [owned release];
783   [_ownedProp release];
784   clang_analyzer_eval(owned == _ownedProp); // expected-warning{{TRUE}}
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}}
795 - (void)testPropertyAccessThenReleaseUnowned {
796   id unowned = [self.unownedProp retain];
797   [unowned release];
798   [_unownedProp release]; // FIXME-warning{{not owned}}
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}}
809 - (void)testPropertyAccessThenReleaseManual {
810   id prop = [self.manualProp retain];
811   [prop release];
812   [_manualProp release]; // no-warning
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
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}}
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}}
838 - (void)testPropertyAccessThenReleaseReadonly {
839   id prop = [self.readonlyProp retain];
840   [prop release];
841   [_readonlyProp release]; // no-warning
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
852 - (void)testPropertyAccessThenReleaseImplicitManual {
853   id prop = [self.implicitManualProp retain];
854   [prop release];
855   [_implicitManualProp release]; // no-warning
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
866 - (void)testPropertyAccessThenReleaseImplicitSynth {
867   id prop = [self.implicitSynthProp retain];
868   [prop release];
869   [_implicitSynthProp release]; // FIXME-warning{{not owned}}
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}}
880 - (id)getUnownedFromProperty {
881   [_ownedProp retain];
882   [_ownedProp autorelease];
883   return _ownedProp; // no-warning
886 - (id)transferUnownedFromProperty {
887   [_ownedProp retain];
888   [_ownedProp autorelease];
889   return [_ownedProp autorelease]; // no-warning
892 - (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) {
893   [_ownedProp retain];
894   [_ownedProp autorelease];
895   return _ownedProp; // no-warning
898 - (void)testAssignOwned:(id)newValue {
899   _ownedProp = newValue;
900   [_ownedProp release]; // FIXME: no-warning{{not owned}}
903 - (void)testAssignUnowned:(id)newValue {
904   _unownedProp = newValue;
905   [_unownedProp release]; // FIXME: no-warning{{not owned}}
908 - (void)testAssignIvarOnly:(id)newValue {
909   _ivarOnly = newValue;
910   [_ivarOnly release]; // FIXME: no-warning{{not owned}}
913 - (void)testAssignCF:(CFTypeRef)newValue {
914   _cfProp = newValue;
915   CFRelease(_cfProp); // FIXME: no-warning{{not owned}}
918 - (void)testAssignReadonly:(id)newValue {
919   _readonlyProp = newValue;
920   [_readonlyProp release]; // FIXME: no-warning{{not owned}}
923 - (void)testAssignImplicitManual:(id)newValue {
924   _implicitManualProp = newValue;
925   [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
928 - (void)testAssignImplicitSynth:(id)newValue {
929   _implicitSynthProp = newValue;
930   [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
933 - (void)testAssignOwnedOkay:(id)newValue {
934   _ownedProp = [newValue retain];
935   [_ownedProp release]; // no-warning
938 - (void)testAssignUnownedOkay:(id)newValue {
939   _unownedProp = [newValue retain];
940   [_unownedProp release]; // no-warning
943 - (void)testAssignIvarOnlyOkay:(id)newValue {
944   _ivarOnly = [newValue retain];
945   [_ivarOnly release]; // no-warning
948 - (void)testAssignCFOkay:(CFTypeRef)newValue {
949   _cfProp = CFRetain(newValue);
950   CFRelease(_cfProp); // no-warning
953 - (void)testAssignReadonlyOkay:(id)newValue {
954   _readonlyProp = [newValue retain];
955   [_readonlyProp release]; // FIXME: no-warning{{not owned}}
958 - (void)testAssignImplicitManualOkay:(id)newValue {
959   _implicitManualProp = [newValue retain];
960   [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
963 - (void)testAssignImplicitSynthOkay:(id)newValue {
964   _implicitSynthProp = [newValue retain];
965   [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
968 // rdar://problem/19862648
969 - (void)establishIvarIsNilDuringLoops {
970   extern id getRandomObject(void);
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   }
983 // rdar://problem/20335433
984 - (void)retainIvarAndInvalidateSelf {
985   extern void invalidate(id);
986   [_unownedProp retain];
987   invalidate(self);
988   [_unownedProp release]; // no-warning
991 @end
993 @interface Wrapper
994 @property(nonatomic, readonly) int value;
995 @end
997 @implementation Wrapper
998 @synthesize value;
999 @end
1001 void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll(void) {
1002    union {
1003     Wrapper *wrapper;
1004    } u = { 0 };
1005    [u.wrapper value];
1008 #endif // non-ARC
1010 @interface ExplicitAccessorInCategory : NSObject
1011 @property(readonly) int normal;
1012 - (int)normal;
1013 @property(readonly) int no_custom_accessor;
1014 @end
1016 @interface ExplicitAccessorInCategory ()
1017 @property(readonly) int in_category;
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
1024 @interface ExplicitAccessorInCategory ()
1025 - (int)in_category;
1027 // This is an ordinary method, not a getter.
1028 - (int)no_custom_accessor;
1029 @end
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}}
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}}
1044 @end
1046 @interface Shadowed
1047 @property (assign) NSObject *o;
1048 - (NSObject *)getShadowedIvar;
1049 - (void)clearShadowedIvar;
1050 - (NSObject *)getShadowedProp;
1051 - (void)clearShadowedProp;
1053 @property (assign) NSObject *o2;
1054 @end
1056 @implementation Shadowed
1057 - (NSObject *)getShadowedIvar {
1058   return self->_o;
1060 - (void)clearShadowedIvar {
1061   self->_o = nil;
1063 - (NSObject *)getShadowedProp {
1064   return self.o;
1066 - (void)clearShadowedProp {
1067   self.o = nil;
1069 @end
1071 @interface Shadowing : Shadowed
1072 @end
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;
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}}
1092 @synthesize o2 = ooo2;
1094 -(void)testPropertyShadowingWithExplicitIvar {
1095   NSObject *oo2 = self.o2; // no-crash
1097 @end