aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/properties.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/properties.m')
-rw-r--r--test/Analysis/properties.m145
1 files changed, 145 insertions, 0 deletions
diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m
new file mode 100644
index 000000000000..ce8faf52736a
--- /dev/null
+++ b/test/Analysis/properties.m
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+-(id)retain;
+@end
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
+-(id)initWithFormat:(NSString *)f,...;
+-(BOOL)isEqualToString:(NSString *)s;
++ (id)string;
+@end
+@interface NSNumber : NSObject {}
++(id)alloc;
+-(id)initWithInteger:(int)i;
+@end
+
+// rdar://6946338
+
+@interface Test1 : NSObject {
+ NSString *text;
+}
+-(id)myMethod;
+@property (nonatomic, assign) NSString *text;
+@end
+
+
+@implementation Test1
+
+@synthesize text;
+
+-(id)myMethod {
+ Test1 *cell = [[[Test1 alloc] init] autorelease];
+
+ NSString *string1 = [[NSString alloc] initWithFormat:@"test %f", 0.0]; // expected-warning {{Potential leak}}
+ cell.text = string1;
+
+ return cell;
+}
+
+@end
+
+
+// rdar://8824416
+
+@interface MyNumber : NSObject
+{
+ NSNumber* _myNumber;
+}
+
+- (id)initWithNumber:(NSNumber *)number;
+
+@property (nonatomic, readonly) NSNumber* myNumber;
+@property (nonatomic, readonly) NSNumber* newMyNumber;
+
+@end
+
+@implementation MyNumber
+@synthesize myNumber=_myNumber;
+
+- (id)initWithNumber:(NSNumber *)number
+{
+ self = [super init];
+
+ if ( self )
+ {
+ _myNumber = [number copy];
+ }
+
+ return self;
+}
+
+- (NSNumber*)newMyNumber
+{
+ if ( _myNumber )
+ return [_myNumber retain];
+
+ return [[NSNumber alloc] initWithInteger:1];
+}
+
+- (id)valueForUndefinedKey:(NSString*)key
+{
+ id value = 0;
+
+ if ([key isEqualToString:@"MyIvarNumberAsPropertyOverReleased"])
+ value = self.myNumber; // _myNumber will be over released, since the value returned from self.myNumber is not retained.
+ else if ([key isEqualToString:@"MyIvarNumberAsPropertyOk"])
+ value = [self.myNumber retain]; // this line fixes the over release
+ else if ([key isEqualToString:@"MyIvarNumberAsNewMyNumber"])
+ value = self.newMyNumber; // this one is ok, since value is returned retained
+ else
+ value = [[NSNumber alloc] initWithInteger:0];
+
+ return [value autorelease]; // expected-warning {{Object sent -autorelease too many times}}
+}
+
+@end
+
+NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
+{
+ NSNumber* result = aMyNumber.myNumber;
+
+ return [result autorelease]; // expected-warning {{Object sent -autorelease too many times}}
+}
+
+
+// rdar://6611873
+
+@interface Person : NSObject {
+ NSString *_name;
+}
+@property (retain) NSString * name;
+@end
+
+@implementation Person
+@synthesize name = _name;
+@end
+
+void rdar6611873() {
+ Person *p = [[[Person alloc] init] autorelease];
+
+ p.name = [[NSString string] retain]; // expected-warning {{leak}}
+ p.name = [[NSString alloc] init]; // expected-warning {{leak}}
+}
+
+@interface SubPerson : Person
+-(NSString *)foo;
+@end
+
+@implementation SubPerson
+-(NSString *)foo {
+ return super.name;
+}
+@end