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