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