retain-release-gc-only.m revision e1cea75e70d76f55157749a7bcad319050492945
1// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc-only %s &&
2// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic-new-cast -verify -fobjc-gc-only %s &&
3// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -fobjc-gc-only -verify %s
4
5//===----------------------------------------------------------------------===//
6// Header stuff.
7//===----------------------------------------------------------------------===//
8
9typedef struct objc_class *Class;
10
11typedef unsigned int __darwin_natural_t;
12typedef struct {} div_t;
13typedef unsigned long UInt32;
14typedef signed long CFIndex;
15typedef const void * CFTypeRef;
16typedef const struct __CFString * CFStringRef;
17typedef const struct __CFAllocator * CFAllocatorRef;
18extern const CFAllocatorRef kCFAllocatorDefault;
19extern CFTypeRef CFRetain(CFTypeRef cf);
20extern void CFRelease(CFTypeRef cf);
21typedef struct {
22}
23CFArrayCallBacks;
24extern const CFArrayCallBacks kCFTypeArrayCallBacks;
25typedef const struct __CFArray * CFArrayRef;
26typedef struct __CFArray * CFMutableArrayRef;
27extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
28extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
29extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
30typedef const struct __CFDictionary * CFDictionaryRef;
31typedef UInt32 CFStringEncoding;
32enum {
33kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
34extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
35typedef double CFTimeInterval;
36typedef CFTimeInterval CFAbsoluteTime;
37extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
38typedef const struct __CFDate * CFDateRef;
39extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
40extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
41typedef __darwin_natural_t natural_t;
42typedef natural_t mach_port_name_t;
43typedef mach_port_name_t mach_port_t;
44typedef struct {
45}
46CFRunLoopObserverContext;
47typedef signed char BOOL;
48typedef unsigned int NSUInteger;
49@class NSString, Protocol;
50extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
51typedef struct _NSZone NSZone;
52@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
53@protocol NSObject  - (BOOL)isEqual:(id)object;
54- (id)retain;
55- (oneway void)release;
56- (id)autorelease;
57@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
58@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
59@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
60@end
61@interface NSObject <NSObject> {}
62- (Class)class;
63+ (id)alloc;
64+ (id)allocWithZone:(NSZone *)zone;
65@end   typedef float CGFloat;
66@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
67- (const char *)UTF8String;
68- (id)initWithUTF8String:(const char *)nullTerminatedCString;
69+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
70- (id)init;
71- (void)dealloc;
72@end   extern NSString * const NSCurrentLocaleDidChangeNotification ;
73@protocol NSLocking  - (void)lock;
74@end  extern NSString * const NSUndoManagerCheckpointNotification;
75typedef enum {
76ACL_READ_DATA = (1<<1),  ACL_LIST_DIRECTORY = (1<<1),  ACL_WRITE_DATA = (1<<2),  ACL_ADD_FILE = (1<<2),  ACL_EXECUTE = (1<<3),  ACL_SEARCH = (1<<3),  ACL_DELETE = (1<<4),  ACL_APPEND_DATA = (1<<5),  ACL_ADD_SUBDIRECTORY = (1<<5),  ACL_DELETE_CHILD = (1<<6),  ACL_READ_ATTRIBUTES = (1<<7),  ACL_WRITE_ATTRIBUTES = (1<<8),  ACL_READ_EXTATTRIBUTES = (1<<9),  ACL_WRITE_EXTATTRIBUTES = (1<<10),  ACL_READ_SECURITY = (1<<11),  ACL_WRITE_SECURITY = (1<<12),  ACL_CHANGE_OWNER = (1<<13) }
77acl_entry_id_t;
78typedef int kern_return_t;
79typedef kern_return_t mach_error_t;
80typedef mach_port_t io_object_t;
81typedef io_object_t io_service_t;
82typedef struct __DASession * DASessionRef;
83extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
84typedef struct __DADisk * DADiskRef;
85extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
86extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
87extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
88extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
89@interface NSResponder : NSObject <NSCoding> {
90}
91@end  @class NSColor, NSFont, NSNotification;
92typedef struct __CFlags {
93}
94_CFlags;
95@interface NSCell : NSObject <NSCopying, NSCoding> {
96}
97@end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
98@interface NSManagedObjectContext : NSObject <NSCoding, NSLocking> {
99}
100@end enum {
101kDAReturnSuccess = 0,     kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
102typedef mach_error_t DAReturn;
103typedef const struct __DADissenter * DADissenterRef;
104extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
105
106CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
107
108static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef 
109cf) {
110    return cf ? (id)CFMakeCollectable(cf) : ((void*)0);
111}
112
113//===----------------------------------------------------------------------===//
114// Test cases.
115//===----------------------------------------------------------------------===//
116
117void f1() {
118  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
119  id x = [(id) A autorelease];
120  CFRelease((CFMutableArrayRef) x);
121}
122
123void f2() {
124  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
125  id x = [(id) A retain];
126  [x release];
127  [x release];
128}
129
130void f3() {
131  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
132  CFMakeCollectable(A);
133  CFRetain(A);
134}
135
136void f3b() {
137  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
138  CFMakeCollectable(A);
139}
140
141
142void f4() {
143  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
144  NSMakeCollectable(A);
145  CFRetain(A);
146}
147
148void f4b() {
149  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
150  NSMakeCollectable(A);
151}
152
153void f5() {
154  id x = [NSMakeCollectable(CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks)) autorelease]; // no-warning
155}
156
157void f5b() {
158  id x = [(id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks) autorelease]; // expected-warning{{leak}}
159}
160
161// Test return of non-owned objects in contexts where an owned object
162// is expected.
163@interface TestReturnNotOwnedWhenExpectedOwned
164- (NSString*)newString;
165- (CFMutableArrayRef)newArray;
166@end
167
168@implementation TestReturnNotOwnedWhenExpectedOwned
169- (NSString*)newString {
170  NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object allocated}}
171  CFRetain(s);
172  return s;
173}
174- (CFMutableArrayRef)newArray{
175   return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
176}
177@end
178
179//===----------------------------------------------------------------------===//
180// <rdar://problem/6948053> False positive: object substitution during -init*
181//   methods warns about returning +0 when using -fobjc-gc-only
182//===----------------------------------------------------------------------===//
183
184@interface MyClassRdar6948053 : NSObject
185- (id) init;
186+ (id) shared;
187@end
188
189@implementation MyClassRdar6948053
190+(id) shared {
191  return (id) 0;
192}
193- (id) init
194{
195  Class myClass = [self class];  
196  [self release];
197  return [[myClass shared] retain]; // no-warning
198}
199@end
200
201//===----------------------------------------------------------------------===//
202// Tests of ownership attributes.
203//===----------------------------------------------------------------------===//
204
205@interface TestOwnershipAttr : NSObject
206- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained));
207- (NSString*) returnsAnOwnedCFString  __attribute__((cf_returns_retained));
208@end
209
210void test_attr_1(TestOwnershipAttr *X) {
211  NSString *str = [X returnsAnOwnedString]; // no-warning
212}
213
214void test_attr_1b(TestOwnershipAttr *X) {
215  NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
216}
217
218@interface MyClassTestCFAttr : NSObject {}
219- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
220- (NSDate*) alsoReturnsRetained;
221- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
222@end
223
224__attribute__((cf_returns_retained))
225CFDateRef returnsRetainedCFDate()  {
226  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
227}
228
229@implementation MyClassTestCFAttr
230- (NSDate*) returnsCFRetained {
231  return (NSDate*) returnsRetainedCFDate(); // No leak.
232}
233
234- (NSDate*) alsoReturnsRetained {
235  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
236}
237
238- (NSDate*) returnsNSRetained {
239  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
240}
241@end