summaryrefslogtreecommitdiff
path: root/test/Analysis/retain-release.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/retain-release.m')
-rw-r--r--test/Analysis/retain-release.m159
1 files changed, 147 insertions, 12 deletions
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 6f8bf09ebd74e..06c510e5dd3ef 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -Wno-objc-root-class %s
#if __has_feature(attribute_ns_returns_retained)
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
@@ -42,6 +42,7 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned int UInt32;
typedef signed long CFIndex;
+typedef CFIndex CFByteOrder;
typedef struct {
CFIndex location;
CFIndex length;
@@ -114,10 +115,15 @@ typedef struct _NSZone NSZone;
- (id)retain;
- (oneway void)release;
- (id)autorelease;
+- (NSString *)description;
- (id)init;
-@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
-@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
-@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
@end
@interface NSObject <NSObject> {}
+ (id)allocWithZone:(NSZone *)zone;
@@ -131,13 +137,22 @@ extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
typedef struct {
}
NSFastEnumerationState;
-@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end @class NSString, NSDictionary;
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSString, NSDictionary;
@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value;
@end @interface NSNumber : NSValue - (char)charValue;
- (id)initWithInt:(int)value;
@end @class NSString;
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt;
++ (id)arrayWithObject:(id)anObject;
++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
++ (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
+- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
+- (id)initWithArray:(NSArray *)array;
@end @interface NSArray (NSArrayCreation) + (id)array;
@end @interface NSAutoreleasePool : NSObject {
}
@@ -157,8 +172,12 @@ typedef double NSTimeInterval;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
-@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
-@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
+@end
+@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
- (void)setObject:(id)anObject forKey:(id)aKey;
@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems;
@end typedef double CGFloat;
@@ -671,7 +690,7 @@ void rdar6704930(unsigned char *s, unsigned int length) {
//===----------------------------------------------------------------------===//
// <rdar://problem/6257780> clang checker fails to catch use-after-release
//===----------------------------------------------------------------------===//
-
+
int rdar_6257780_Case1() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *array = [NSArray array];
@@ -681,6 +700,15 @@ int rdar_6257780_Case1() {
}
//===----------------------------------------------------------------------===//
+// <rdar://problem/10640253> Analyzer is confused about NSAutoreleasePool -allocWithZone:.
+//===----------------------------------------------------------------------===//
+
+void rdar_10640253_autorelease_allocWithZone() {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init];
+ (void) pool;
+}
+
+//===----------------------------------------------------------------------===//
// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs
//===----------------------------------------------------------------------===//
@@ -1458,7 +1486,7 @@ static void rdar_8724287(CFErrorRef error)
while (error_to_dump != ((void*)0)) {
CFDictionaryRef info;
- info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object allocated on line}}
+ info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}}
if (info != ((void*)0)) {
}
@@ -1604,3 +1632,110 @@ void rdar10232019_positive() {
NSLog(@"%@", otherString);
}
+// RetainCountChecker support for XPC.
+// <rdar://problem/9658496>
+typedef void * xpc_object_t;
+xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf);
+void xpc_release(xpc_object_t object);
+
+void rdar9658496() {
+ CFStringRef cf;
+ xpc_object_t xpc;
+ cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning
+ xpc = _CFXPCCreateXPCObjectFromCFObject( cf );
+ CFRelease(cf);
+ xpc_release(xpc);
+}
+
+// Support annotations with method families.
+@interface RDar10824732 : NSObject
+- (id)initWithObj:(id CF_CONSUMED)obj;
+@end
+
+@implementation RDar10824732
+- (id)initWithObj:(id)obj {
+ [obj release];
+ return [super init];
+}
+@end
+
+void rdar_10824732() {
+ @autoreleasepool {
+ NSString *obj = @"test";
+ RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning
+ [foo release];
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Test returning allocated memory in a struct.
+//
+// We currently don't have a general way to track pointers that "escape".
+// Here we test that RetainCountChecker doesn't get excited about returning
+// allocated CF objects in struct fields.
+//===----------------------------------------------------------------------===//
+void *malloc(size_t);
+struct rdar11104566 { CFStringRef myStr; };
+struct rdar11104566 test_rdar11104566() {
+ CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning
+ struct rdar11104566 V;
+ V.myStr = cf;
+ return V; // no-warning
+}
+
+struct rdar11104566 *test_2_rdar11104566() {
+ CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning
+ struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V));
+ V->myStr = cf;
+ return V; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// ObjC literals support.
+//===----------------------------------------------------------------------===//
+
+void test_objc_arrays() {
+ { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY
+ NSObject *o = [[NSObject alloc] init];
+ NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}}
+ [o release];
+ [a description];
+ [o description];
+ }
+
+ { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY
+ NSObject *o = [[NSObject alloc] init];
+ NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0];
+ NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}}
+ [o release];
+ [a2 description];
+ [o description];
+ }
+
+ { // CASE THREE -- OBJECT IN RETAINED @[]
+ NSObject *o = [[NSObject alloc] init];
+ NSArray *a3 = [@[o] retain]; // expected-warning {{leak}}
+ [o release];
+ [a3 description];
+ [o description];
+ }
+
+ { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[]
+ NSObject *o = [[NSObject alloc] init];
+ NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}}
+ [o release];
+
+ [a description];
+ [o description];
+ }
+
+ { // CASE FIVE -- OBJECT IN RETAINED @{}
+ NSValue *o = [[NSValue alloc] init];
+ NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}}
+ [o release];
+
+ [a description];
+ [o description];
+ }
+}
+