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