[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / Analysis / properties.m
blobf26245db841c1e1b549cfe9a597dbf319e284126
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 @interface Test1 : NSObject {
41   NSString *text;
43 -(id)myMethod;
44 @property (nonatomic, assign) NSString *text;
45 @end
48 #if !__has_feature(objc_arc)
50 @implementation Test1
52 @synthesize text;
54 -(id)myMethod {
55   Test1 *cell = [[[Test1 alloc] init] autorelease];
57   NSString *string1 = [[NSString alloc] initWithFormat:@"test %f", 0.0]; // expected-warning {{Potential leak}}
58   cell.text = string1;
60   return cell;
63 @end
66 @interface MyNumber : NSObject
68   NSNumber* _myNumber;
71 - (id)initWithNumber:(NSNumber *)number;
73 @property (nonatomic, readonly) NSNumber* myNumber;
74 @property (nonatomic, readonly) NSNumber* newMyNumber;
76 @end
78 @implementation MyNumber
79 @synthesize myNumber=_myNumber;
81 - (id)initWithNumber:(NSNumber *)number
83   self = [super init];
84   
85   if ( self )
86   {
87     _myNumber = [number copy];
88   }
89   
90   return self;
93 - (NSNumber*)newMyNumber
95   if ( _myNumber )
96     return [_myNumber retain];
97   
98   return [[NSNumber alloc] initWithInteger:1];
101 - (id)valueForUndefinedKey:(NSString*)key
103   id value = 0;
104   
105   if ([key isEqualToString:@"MyIvarNumberAsPropertyOverReleased"])
106     value = self.myNumber; // _myNumber will be over released, since the value returned from self.myNumber is not retained.
107   else if ([key isEqualToString:@"MyIvarNumberAsPropertyOk"])
108     value = [self.myNumber retain]; // this line fixes the over release
109   else if ([key isEqualToString:@"MyIvarNumberAsNewMyNumber"])
110     value = self.newMyNumber; // this one is ok, since value is returned retained
111   else 
112     value = [[NSNumber alloc] initWithInteger:0];
113   
114   return [value autorelease]; // expected-warning {{Object autoreleased too many times}}
117 @end
119 NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
121   NSNumber* result = aMyNumber.myNumber;
122     
123   return [result autorelease]; // expected-warning {{Object autoreleased too many times}}
126 #endif
129 @interface Person : NSObject {
130   NSString *_name;
132 @property (retain) NSString * name;
133 @property (assign) id friend;
134 @end
136 @implementation Person
137 @synthesize name = _name;
139 -(void)dealloc {
140 #if !__has_feature(objc_arc)
141   self.name = [[NSString alloc] init]; // expected-warning {{leak}}
143   [super dealloc]; // expected-warning {{The '_name' ivar in 'Person' was retained by a synthesized property but not released before '[super dealloc]}}
144 #endif
146 @end
148 #if !__has_feature(objc_arc)
149 void rdar6611873(void) {
150   Person *p = [[[Person alloc] init] autorelease];
151   
152   p.name = [[NSString string] retain]; // expected-warning {{leak}}
153   p.name = [[NSString alloc] init]; // expected-warning {{leak}}
155   p.friend = [[Person alloc] init]; // expected-warning {{leak}}
157 #endif
159 @interface SubPerson : Person
160 -(NSString *)foo;
161 @end
163 @implementation SubPerson
164 -(NSString *)foo {
165   return super.name;
167 @end
170 #if !__has_feature(objc_arc)
171 // Static analyzer doesn't detect uninitialized variable issues for property accesses
172 @interface RDar9241180
173 @property (readwrite,assign) id x;
174 -(id)testAnalyzer1:(int) y;
175 -(void)testAnalyzer2;
176 @end
178 @implementation RDar9241180
179 @synthesize x;
180 -(id)testAnalyzer1:(int)y {
181     RDar9241180 *o;
182     if (y && o.x) // expected-warning {{Property access on an uninitialized object pointer}}
183       return o;
184     return o; // expected-warning {{Undefined or garbage value returned to caller}}
186 -(void)testAnalyzer2 {
187   id y;
188   self.x = y;  // expected-warning {{Argument for property setter is an uninitialized value}}
190 @end
191 #endif
194 //------
195 // Property accessor synthesis
196 //------
198 extern void doSomethingWithPerson(Person *p);
199 extern void doSomethingWithName(NSString *name);
201 void testConsistencyRetain(Person *p) {
202   clang_analyzer_eval(p.name == p.name); // expected-warning{{TRUE}}
204   id origName = p.name;
205   clang_analyzer_eval(p.name == origName); // expected-warning{{TRUE}}
206   doSomethingWithPerson(p);
207   clang_analyzer_eval(p.name == origName); // expected-warning{{UNKNOWN}}
210 void testConsistencyAssign(Person *p) {
211   clang_analyzer_eval(p.friend == p.friend); // expected-warning{{TRUE}}
213   id origFriend = p.friend;
214   clang_analyzer_eval(p.friend == origFriend); // expected-warning{{TRUE}}
215   doSomethingWithPerson(p);
216   clang_analyzer_eval(p.friend == origFriend); // expected-warning{{UNKNOWN}}
219 @interface ClassWithShadowedReadWriteProperty {
220   int _f;
222 @property (readonly) int someProp;
223 @end
225 @interface ClassWithShadowedReadWriteProperty ()
226 @property (readwrite) int someProp;
227 @end
229 @implementation ClassWithShadowedReadWriteProperty
230 - (void)testSynthesisForShadowedReadWriteProperties; {
231   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
233   _f = 1;
235   // Read of shadowed property should not invalidate receiver.
236   (void)self.someProp;
237   clang_analyzer_eval(_f == 1); // expected-warning{{TRUE}}
239   _f = 2;
240   // Call to getter of shadowed property should not invalidate receiver.
241   (void)[self someProp];
242   clang_analyzer_eval(_f == 2); // expected-warning{{TRUE}}
244 @end
246 // Tests for the analyzer fix that works around a Sema bug
247 // where multiple methods are created for properties in class extensions that
248 // are redeclared in a category method.
249 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory
250 @end
252 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
253 @end
255 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
256 @property (readwrite) int someProp;
257 @property (readonly) int otherProp;
258 @end
260 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory (MyCat)
261 @property (readonly) int someProp;
262 @property (readonly) int otherProp;
263 @end
265 @implementation ClassWithRedeclaredPropertyInExtensionFollowedByCategory
266 - (void)testSynthesisForRedeclaredProperties; {
267   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
268   clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}}
270   clang_analyzer_eval(self.otherProp == self.otherProp); // expected-warning{{TRUE}}
271   clang_analyzer_eval([self otherProp] == self.otherProp); // expected-warning{{TRUE}}
273 @end
275 // The relative order of the extension and the category matter, so test both.
276 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension
277 @end
279 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension ()
280 @property (readwrite) int someProp;
281 @end
283 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension (MyCat)
284 @property (readonly) int someProp;
285 @end
287 @implementation ClassWithRedeclaredPropertyInCategoryFollowedByExtension
288 - (void)testSynthesisForRedeclaredProperties; {
289   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
290   clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}}
292 @end
294 @interface ClassWithSynthesizedPropertyAndGetter
295 @property (readonly) int someProp;
296 @end
298 @implementation ClassWithSynthesizedPropertyAndGetter
299 @synthesize someProp;
301 // Make sure that the actual getter is inlined and not a getter created
302 // by BodyFarm
303 - (void)testBodyFarmGetterNotUsed {
304   int i = self.someProp;
305   clang_analyzer_eval(i == 22); // expected-warning {{TRUE}}
308 -(int)someProp {
309   return 22;
311 @end
313 __attribute__((objc_root_class))
314 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
315 @end
317 @protocol HasStuff
318 @property (nonatomic, readonly) int stuffProperty;
319 @end
321 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private)
322 @property (nonatomic, readonly) int stuffProperty;
323 @end
325 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff>
326 @end
328 @interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff>
329 @end
331 @implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
332 @synthesize stuffProperty = _stuffProperty;
334 -(void)foo {
335   (void)self.stuffProperty;
337 @end
339 //------
340 // Setter ivar invalidation.
341 //------
343 @interface ClassWithSetters
344 // Note: These properties have implicit @synthesize implementations to be
345 // backed with ivars.
346 @property (assign) int propWithIvar1;
347 @property (assign) int propWithIvar2;
349 @property (retain) NSNumber *retainedProperty;
351 @end
353 @interface ClassWithSetters (InOtherTranslationUnit)
354 // The implementation of this property is in another translation unit.
355 // We don't know whether it is backed by an ivar or not.
356 @property (assign) int propInOther;
357 @end
359 @implementation ClassWithSetters
360 - (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; {
361   _propWithIvar1 = 1;
362   _propWithIvar2 = 2;
363   self.propWithIvar1 = 66;
365   // Calling the setter of a property backed by the instance variable
366   // should invalidate the storage for the instance variable but not
367   // the rest of the receiver. Ideally we would model the setter completely
368   // but doing so would cause the new value to escape when it is bound
369   // to the ivar. This would cause bad false negatives in the retain count
370   // checker. (There is a test for this scenario in
371   // testWriteRetainedValueToRetainedProperty below).
372   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
373   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}
375   _propWithIvar1 = 1;
376   [self setPropWithIvar1:66];
378   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
379   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}
382 - (void) testSettingPropWithoutIvarInvalidatesEntireInstance; {
383   _propWithIvar1 = 1;
384   _propWithIvar2 = 2;
385   self.propInOther = 66;
387   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
388   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
390   _propWithIvar1 = 1;
391   _propWithIvar2 = 2;
392   [self setPropInOther:66];
394   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
395   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
398 #if !__has_feature(objc_arc)
399 - (void) testWriteRetainedValueToRetainedProperty; {
400   NSNumber *number = [[NSNumber alloc] initWithInteger:5]; // expected-warning {{Potential leak of an object stored into 'number'}}
402   // Make sure we catch this leak.
403   self.retainedProperty = number;
405 #endif
406 @end
408 //------
409 // class properties
410 //------
412 int gBackingForReadWriteClassProp = 0;
414 @interface ClassWithClassProperties
415 @property(class, readonly) int readOnlyClassProp;
417 @property(class) int readWriteClassProp;
419 // Make sure we handle when a class and instance property have the same
420 // name. Test both when instance comes first and when class comes first.
421 @property(readonly) int classAndInstancePropWithSameNameOrderInstanceFirst;
422 @property(class, readonly) int classAndInstancePropWithSameNameOrderInstanceFirst;
424 @property(class, readonly) int classAndInstancePropWithSameNameOrderClassFirst;
425 @property(readonly) int classAndInstancePropWithSameNameOrderClassFirst;
428 @property(class, readonly) int dynamicClassProp;
430 @end
432 @interface ClassWithClassProperties (OtherTranslationUnit)
433 @property(class, assign) id propInOtherTranslationUnit;
434 @end
436 @implementation ClassWithClassProperties
438 @dynamic dynamicClassProp;
440 + (int)readOnlyClassProp {
441   return 1;
444 + (int)readWriteClassProp {
445   return gBackingForReadWriteClassProp;
448 + (void)setReadWriteClassProp:(int)val {
449   gBackingForReadWriteClassProp = val;
452 - (int)classAndInstancePropWithSameNameOrderInstanceFirst {
453   return 12;
456 + (int)classAndInstancePropWithSameNameOrderInstanceFirst {
457   return 13;
460 + (int)classAndInstancePropWithSameNameOrderClassFirst {
461   return 14;
464 - (int)classAndInstancePropWithSameNameOrderClassFirst {
465   return 15;
468 - (void)testInlineClassProp {
469   clang_analyzer_eval(ClassWithClassProperties.readOnlyClassProp == 1); // expected-warning{{TRUE}}
471   ClassWithClassProperties.readWriteClassProp = 7;
472   clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 7); // expected-warning{{TRUE}}
473   ClassWithClassProperties.readWriteClassProp = 8;
474   clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 8); // expected-warning{{TRUE}}
477 - (void)testUnknownClassProp {
478   clang_analyzer_eval(ClassWithClassProperties.propInOtherTranslationUnit == ClassWithClassProperties.propInOtherTranslationUnit); // expected-warning{{UNKNOWN}}
481 - (void)testEscapeGlobalOnUnknownProp {
482   gBackingForReadWriteClassProp = 33;
483   ClassWithClassProperties.propInOtherTranslationUnit = 0;
484   clang_analyzer_eval(gBackingForReadWriteClassProp == 33); // expected-warning{{UNKNOWN}}
487 - (void)testClassAndInstancePropertyWithSameName {
488   clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderInstanceFirst == 12); // expected-warning{{TRUE}}
489   clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderInstanceFirst == 13); // expected-warning{{TRUE}}
491   clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderClassFirst == 14); // expected-warning{{TRUE}}
492   clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderClassFirst == 15); // expected-warning{{TRUE}}
495 - (void)testDynamicClassProp {
496   clang_analyzer_eval(ClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{UNKNOWN}}
499 @end
501 @interface SubclassOfClassWithClassProperties : ClassWithClassProperties
502 @end
504 @implementation SubclassOfClassWithClassProperties
505 + (int)dynamicClassProp; {
506  return 16;
509 - (void)testDynamicClassProp {
510   clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}}
513 @end
516 #if !__has_feature(objc_arc)
517 void testOverrelease(Person *p, int coin) {
518   switch (coin) {
519   case 0:
520     [p.name release]; // expected-warning{{not owned}}
521     break;
522   case 1:
523     [p.friend release]; // expected-warning{{not owned}}
524     break;
525   case 2: {
526     id friend = p.friend;
527     doSomethingWithPerson(p);
528     [friend release]; // expected-warning{{not owned}}
529   }
530   }
533 @implementation Person (Rdar16333368)
535 - (void)testDeliberateRelease:(Person *)other {
536   doSomethingWithName(self.name);
537   [_name release]; // no-warning
538   self->_name = 0;
540   doSomethingWithName(other->_name);
541   [other.name release]; // no-warning
544 - (void)deliberateReleaseFalseNegative {
545   // This is arguably a false negative because the result of p.friend shouldn't
546   // be released, even though we are manipulating the ivar in between the two
547   // actions.
548   id name = self.name;
549   _name = 0;
550   [name release];
553 - (void)testRetainAndRelease {
554   [self.name retain];
555   [self.name release];
556   [self.name release]; // expected-warning{{not owned}}
559 - (void)testRetainAndReleaseIVar {
560   [self.name retain];
561   [_name release];
562   [_name release];
565 @end
566 #endif
568 @interface IntWrapper
569 @property int value;
570 @end
572 @implementation IntWrapper
573 @synthesize value;
574 @end
576 void testConsistencyInt(IntWrapper *w) {
577   clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
579   int origValue = w.value;
580   if (origValue != 42)
581     return;
583   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
586 void testConsistencyInt2(IntWrapper *w) {
587   if (w.value != 42)
588     return;
590   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
594 @interface IntWrapperAuto
595 @property int value;
596 @end
598 @implementation IntWrapperAuto
599 @end
601 void testConsistencyIntAuto(IntWrapperAuto *w) {
602   clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
604   int origValue = w.value;
605   if (origValue != 42)
606     return;
608   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
611 void testConsistencyIntAuto2(IntWrapperAuto *w) {
612   if (w.value != 42)
613     return;
615   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
619 typedef struct {
620   int value;
621 } IntWrapperStruct;
623 @interface StructWrapper
624 @property IntWrapperStruct inner;
625 @end
627 @implementation StructWrapper
628 @synthesize inner;
629 @end
631 void testConsistencyStruct(StructWrapper *w) {
632   clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}
634   int origValue = w.inner.value;
635   if (origValue != 42)
636     return;
638   clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
642 @interface OpaqueIntWrapper
643 @property int value;
644 @end
646 // For now, don't assume a property is implemented using an ivar unless we can
647 // actually see that it is.
648 void testOpaqueConsistency(OpaqueIntWrapper *w) {
649   clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}}
653 #if !__has_feature(objc_arc)
654 // Test quite a few cases of retain/release issues.
656 @interface RetainCountTesting
657 @property (strong) id ownedProp;
658 @property (unsafe_unretained) id unownedProp;
659 @property (nonatomic, strong) id manualProp;
660 @property (readonly) id readonlyProp;
661 @property (nonatomic, readwrite/*, assign */) id implicitManualProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}}
662 @property (nonatomic, readwrite/*, assign */) id implicitSynthProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}}
663 @property CFTypeRef cfProp;
664 @end
666 @implementation RetainCountTesting {
667   id _ivarOnly;
670 - (id)manualProp {
671   return _manualProp;
674 - (void)setImplicitManualProp:(id)newValue {}
676 - (void)testOverreleaseOwnedIvar {
677   [_ownedProp retain];
678   [_ownedProp release];
679   [_ownedProp release];
680   [_ownedProp release]; // FIXME-warning{{used after it is released}}
683 - (void)testOverreleaseUnownedIvar {
684   [_unownedProp retain];
685   [_unownedProp release];
686   [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}}
689 - (void)testOverreleaseIvarOnly {
690   [_ivarOnly retain];
691   [_ivarOnly release];
692   [_ivarOnly release];
693   [_ivarOnly release]; // FIXME-warning{{used after it is released}}
696 - (void)testOverreleaseReadonlyIvar {
697   [_readonlyProp retain];
698   [_readonlyProp release];
699   [_readonlyProp release];
700   [_readonlyProp release]; // FIXME-warning{{used after it is released}}
703 - (void)testOverreleaseImplicitManualIvar {
704   [_implicitManualProp retain];
705   [_implicitManualProp release];
706   [_implicitManualProp release];
707   [_implicitManualProp release]; // FIXME-warning{{used after it is released}}
710 - (void)testOverreleaseImplicitSynthIvar {
711   [_implicitSynthProp retain];
712   [_implicitSynthProp release];
713   [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}}
716 - (void)testOverreleaseCF {
717   CFRetain(_cfProp);
718   CFRelease(_cfProp);
719   CFRelease(_cfProp);
720   CFRelease(_cfProp); // FIXME-warning{{used after it is released}}
723 - (void)testOverreleaseOwnedIvarUse {
724   [_ownedProp retain];
725   [_ownedProp release];
726   [_ownedProp release];
727   [_ownedProp myMethod]; // FIXME-warning{{used after it is released}}
730 - (void)testOverreleaseIvarOnlyUse {
731   [_ivarOnly retain];
732   [_ivarOnly release];
733   [_ivarOnly release];
734   [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}}
737 - (void)testOverreleaseCFUse {
738   CFRetain(_cfProp);
739   CFRelease(_cfProp);
740   CFRelease(_cfProp);
742   extern void CFUse(CFTypeRef);
743   CFUse(_cfProp); // FIXME-warning{{used after it is released}}
746 - (void)testOverreleaseOwnedIvarAutoreleaseOkay {
747   [_ownedProp retain];
748   [_ownedProp release];
749   [_ownedProp autorelease];
750 } // no-warning
752 - (void)testOverreleaseIvarOnlyAutoreleaseOkay {
753   [_ivarOnly retain];
754   [_ivarOnly release];
755   [_ivarOnly autorelease];
756 } // no-warning
758 - (void)testOverreleaseOwnedIvarAutorelease {
759   [_ownedProp retain];
760   [_ownedProp release];
761   [_ownedProp autorelease];
762   [_ownedProp autorelease];
763 } // FIXME-warning{{Object autoreleased too many times}}
765 - (void)testOverreleaseIvarOnlyAutorelease {
766   [_ivarOnly retain];
767   [_ivarOnly release];
768   [_ivarOnly autorelease];
769   [_ivarOnly autorelease];
770 } // FIXME-warning{{Object autoreleased too many times}}
772 - (void)testPropertyAccessThenReleaseOwned {
773   id owned = [self.ownedProp retain];
774   [owned release];
775   [_ownedProp release];
776   clang_analyzer_eval(owned == _ownedProp); // expected-warning{{TRUE}}
779 - (void)testPropertyAccessThenReleaseOwned2 {
780   id fromIvar = _ownedProp;
781   id owned = [self.ownedProp retain];
782   [owned release];
783   [fromIvar release];
784   clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}}
787 - (void)testPropertyAccessThenReleaseUnowned {
788   id unowned = [self.unownedProp retain];
789   [unowned release];
790   [_unownedProp release]; // FIXME-warning{{not owned}}
793 - (void)testPropertyAccessThenReleaseUnowned2 {
794   id fromIvar = _unownedProp;
795   id unowned = [self.unownedProp retain];
796   [unowned release];
797   clang_analyzer_eval(unowned == fromIvar); // expected-warning{{TRUE}}
798   [fromIvar release]; // FIXME-warning{{not owned}}
801 - (void)testPropertyAccessThenReleaseManual {
802   id prop = [self.manualProp retain];
803   [prop release];
804   [_manualProp release]; // no-warning
807 - (void)testPropertyAccessThenReleaseManual2 {
808   id fromIvar = _manualProp;
809   id prop = [self.manualProp retain];
810   [prop release];
811   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
812   [fromIvar release]; // no-warning
815 - (void)testPropertyAccessThenReleaseCF {
816   CFTypeRef owned = CFRetain(self.cfProp);
817   CFRelease(owned);
818   CFRelease(_cfProp); // no-warning
819   clang_analyzer_eval(owned == _cfProp); // expected-warning{{TRUE}}
822 - (void)testPropertyAccessThenReleaseCF2 {
823   CFTypeRef fromIvar = _cfProp;
824   CFTypeRef owned = CFRetain(self.cfProp);
825   CFRelease(owned);
826   CFRelease(fromIvar);
827   clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}}
830 - (void)testPropertyAccessThenReleaseReadonly {
831   id prop = [self.readonlyProp retain];
832   [prop release];
833   [_readonlyProp release]; // no-warning
836 - (void)testPropertyAccessThenReleaseReadonly2 {
837   id fromIvar = _readonlyProp;
838   id prop = [self.readonlyProp retain];
839   [prop release];
840   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
841   [fromIvar release]; // no-warning
844 - (void)testPropertyAccessThenReleaseImplicitManual {
845   id prop = [self.implicitManualProp retain];
846   [prop release];
847   [_implicitManualProp release]; // no-warning
850 - (void)testPropertyAccessThenReleaseImplicitManual2 {
851   id fromIvar = _implicitManualProp;
852   id prop = [self.implicitManualProp retain];
853   [prop release];
854   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
855   [fromIvar release]; // no-warning
858 - (void)testPropertyAccessThenReleaseImplicitSynth {
859   id prop = [self.implicitSynthProp retain];
860   [prop release];
861   [_implicitSynthProp release]; // FIXME-warning{{not owned}}
864 - (void)testPropertyAccessThenReleaseImplicitSynth2 {
865   id fromIvar = _implicitSynthProp;
866   id prop = [self.implicitSynthProp retain];
867   [prop release];
868   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
869   [fromIvar release]; // FIXME-warning{{not owned}}
872 - (id)getUnownedFromProperty {
873   [_ownedProp retain];
874   [_ownedProp autorelease];
875   return _ownedProp; // no-warning
878 - (id)transferUnownedFromProperty {
879   [_ownedProp retain];
880   [_ownedProp autorelease];
881   return [_ownedProp autorelease]; // no-warning
884 - (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) {
885   [_ownedProp retain];
886   [_ownedProp autorelease];
887   return _ownedProp; // no-warning
890 - (void)testAssignOwned:(id)newValue {
891   _ownedProp = newValue;
892   [_ownedProp release]; // FIXME: no-warning{{not owned}}
895 - (void)testAssignUnowned:(id)newValue {
896   _unownedProp = newValue;
897   [_unownedProp release]; // FIXME: no-warning{{not owned}}
900 - (void)testAssignIvarOnly:(id)newValue {
901   _ivarOnly = newValue;
902   [_ivarOnly release]; // FIXME: no-warning{{not owned}}
905 - (void)testAssignCF:(CFTypeRef)newValue {
906   _cfProp = newValue;
907   CFRelease(_cfProp); // FIXME: no-warning{{not owned}}
910 - (void)testAssignReadonly:(id)newValue {
911   _readonlyProp = newValue;
912   [_readonlyProp release]; // FIXME: no-warning{{not owned}}
915 - (void)testAssignImplicitManual:(id)newValue {
916   _implicitManualProp = newValue;
917   [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
920 - (void)testAssignImplicitSynth:(id)newValue {
921   _implicitSynthProp = newValue;
922   [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
925 - (void)testAssignOwnedOkay:(id)newValue {
926   _ownedProp = [newValue retain];
927   [_ownedProp release]; // no-warning
930 - (void)testAssignUnownedOkay:(id)newValue {
931   _unownedProp = [newValue retain];
932   [_unownedProp release]; // no-warning
935 - (void)testAssignIvarOnlyOkay:(id)newValue {
936   _ivarOnly = [newValue retain];
937   [_ivarOnly release]; // no-warning
940 - (void)testAssignCFOkay:(CFTypeRef)newValue {
941   _cfProp = CFRetain(newValue);
942   CFRelease(_cfProp); // no-warning
945 - (void)testAssignReadonlyOkay:(id)newValue {
946   _readonlyProp = [newValue retain];
947   [_readonlyProp release]; // FIXME: no-warning{{not owned}}
950 - (void)testAssignImplicitManualOkay:(id)newValue {
951   _implicitManualProp = [newValue retain];
952   [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
955 - (void)testAssignImplicitSynthOkay:(id)newValue {
956   _implicitSynthProp = [newValue retain];
957   [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
960 - (void)establishIvarIsNilDuringLoops {
961   extern id getRandomObject(void);
963   int i = 4; // Must be at least 4 to trigger the bug.
964   while (--i) {
965     id x = 0;
966     if (getRandomObject())
967       x = _ivarOnly;
968     if (!x)
969       x = getRandomObject();
970     [x myMethod];
971   }
974 - (void)retainIvarAndInvalidateSelf {
975   extern void invalidate(id);
976   [_unownedProp retain];
977   invalidate(self);
978   [_unownedProp release]; // no-warning
981 @end
983 @interface Wrapper
984 @property(nonatomic, readonly) int value;
985 @end
987 @implementation Wrapper
988 @synthesize value;
989 @end
991 void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll(void) {
992    union {
993     Wrapper *wrapper;
994    } u = { 0 };
995    [u.wrapper value];
998 #endif // non-ARC
1000 @interface ExplicitAccessorInCategory : NSObject
1001 @property(readonly) int normal;
1002 - (int)normal;
1003 @property(readonly) int no_custom_accessor;
1004 @end
1006 @interface ExplicitAccessorInCategory ()
1007 @property(readonly) int in_category;
1009 @property(readonly) int still_no_custom_accessor;
1010 // This is an ordinary method, not a getter.
1011 - (int)still_no_custom_accessor;
1012 @end
1014 @interface ExplicitAccessorInCategory ()
1015 - (int)in_category;
1017 // This is an ordinary method, not a getter.
1018 - (int)no_custom_accessor;
1019 @end
1021 @implementation ExplicitAccessorInCategory
1022 - (void)foo {
1023         // Make sure we don't farm bodies for explicit accessors: in particular,
1024         // we're not sure that the accessor always returns the same value.
1025         clang_analyzer_eval(self.normal == self.normal); // expected-warning{{UNKNOWN}}
1026         // Also this used to crash.
1027         clang_analyzer_eval(self.in_category == self.in_category); // expected-warning{{UNKNOWN}}
1029         // When there is no explicit accessor defined (even if it looks like there is),
1030         // farm the getter body and see if it does actually always yield the same value.
1031         clang_analyzer_eval(self.no_custom_accessor == self.no_custom_accessor); // expected-warning{{TRUE}}
1032         clang_analyzer_eval(self.still_no_custom_accessor == self.still_no_custom_accessor); // expected-warning{{TRUE}}
1034 @end
1036 @interface Shadowed
1037 @property (assign) NSObject *o;
1038 - (NSObject *)getShadowedIvar;
1039 - (void)clearShadowedIvar;
1040 - (NSObject *)getShadowedProp;
1041 - (void)clearShadowedProp;
1043 @property (assign) NSObject *o2;
1044 @end
1046 @implementation Shadowed
1047 - (NSObject *)getShadowedIvar {
1048   return self->_o;
1050 - (void)clearShadowedIvar {
1051   self->_o = nil;
1053 - (NSObject *)getShadowedProp {
1054   return self.o;
1056 - (void)clearShadowedProp {
1057   self.o = nil;
1059 @end
1061 @interface Shadowing : Shadowed
1062 @end
1064 @implementation Shadowing
1065 // Property 'o' is declared in the superclass but synthesized here.
1066 // This creates a separate ivar that shadows the superclass's ivar,
1067 // but the old ivar is still accessible from the methods of the superclass.
1068 // The old property, however, is not accessible with the property syntax
1069 // even from the superclass methods.
1070 @synthesize o;
1072 -(void)testPropertyShadowing {
1073   NSObject *oo = self.o; // no-crash
1074   clang_analyzer_eval(self.o == oo); // expected-warning{{TRUE}}
1075   clang_analyzer_eval([self getShadowedIvar] == oo); // expected-warning{{UNKNOWN}}
1076   [self clearShadowedIvar];
1077   clang_analyzer_eval(self.o == oo); // expected-warning{{TRUE}}
1078   clang_analyzer_eval([self getShadowedIvar] == oo); // expected-warning{{UNKNOWN}}
1079   clang_analyzer_eval([self getShadowedIvar] == nil); // expected-warning{{TRUE}}
1082 @synthesize o2 = ooo2;
1084 -(void)testPropertyShadowingWithExplicitIvar {
1085   NSObject *oo2 = self.o2; // no-crash
1087 @end