retain-release.m revision 79f7f8ab9a8c741e29ea9e648d05f774de49cd9b
1// RUN: clang -analyze -checker-cfref -verify %s &&
2// RUN: clang -analyze -checker-cfref -analyzer-store=region -verify %s
3
4
5//===----------------------------------------------------------------------===//
6// The following code is reduced using delta-debugging from
7// Foundation.h (Mac OS X).
8//
9// It includes the basic definitions for the test cases below.
10// Not including Foundation.h directly makes this test case both svelte and
11// portable to non-Mac platforms.
12//===----------------------------------------------------------------------===//
13
14typedef unsigned int __darwin_natural_t;
15typedef unsigned long UInt32;
16typedef signed long CFIndex;
17typedef const void * CFTypeRef;
18typedef const struct __CFString * CFStringRef;
19typedef const struct __CFAllocator * CFAllocatorRef;
20extern const CFAllocatorRef kCFAllocatorDefault;
21extern CFTypeRef CFRetain(CFTypeRef cf);
22extern void CFRelease(CFTypeRef cf);
23typedef struct {
24}
25CFArrayCallBacks;
26extern const CFArrayCallBacks kCFTypeArrayCallBacks;
27typedef const struct __CFArray * CFArrayRef;
28typedef struct __CFArray * CFMutableArrayRef;
29extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
30extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
31typedef const struct __CFDictionary * CFDictionaryRef;
32typedef UInt32 CFStringEncoding;
33enum {
34kCFStringEncodingMacRoman = 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  };
35extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
36typedef double CFTimeInterval;
37typedef CFTimeInterval CFAbsoluteTime;
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 signed char BOOL;
45typedef struct _NSZone NSZone;
46@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
47@protocol NSObject  - (BOOL)isEqual:(id)object;
48- (id)retain;
49- (oneway void)release;
50- (id)autorelease;
51@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
52@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
53@end    @interface NSObject <NSObject> {
54}
55@end  typedef float CGFloat;
56typedef double NSTimeInterval;
57@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
58@end      enum {
59NSObjCNoType = 0,     NSObjCVoidType = 'v',     NSObjCCharType = 'c',     NSObjCShortType = 's',     NSObjCLongType = 'l',     NSObjCLonglongType = 'q',     NSObjCFloatType = 'f',     NSObjCDoubleType = 'd',      NSObjCBoolType = 'B',      NSObjCSelectorType = ':',     NSObjCObjectType = '@',     NSObjCStructType = '{',     NSObjCPointerType = '^',     NSObjCStringType = '*',     NSObjCArrayType = '[',     NSObjCUnionType = '(',     NSObjCBitfield = 'b' }
60__attribute__((deprecated));
61typedef int kern_return_t;
62typedef kern_return_t mach_error_t;
63typedef mach_port_t io_object_t;
64typedef io_object_t io_service_t;
65typedef struct __DASession * DASessionRef;
66extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
67typedef struct __DADisk * DADiskRef;
68extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
69extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
70extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
71extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
72@interface NSAppleEventManager : NSObject {
73}
74@end enum {
75kDAReturnSuccess = 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 };
76typedef mach_error_t DAReturn;
77typedef const struct __DADissenter * DADissenterRef;
78extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
79
80//===----------------------------------------------------------------------===//
81// Test cases.
82//===----------------------------------------------------------------------===//
83
84CFAbsoluteTime f1() {
85  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
86  CFDateRef date = CFDateCreate(0, t);
87  CFRetain(date);
88  CFRelease(date);
89  CFDateGetAbsoluteTime(date); // no-warning
90  CFRelease(date);
91  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
92  return t;
93}
94
95CFAbsoluteTime f2() {
96  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
97  CFDateRef date = CFDateCreate(0, t);  
98  [((NSDate*) date) retain];
99  CFRelease(date);
100  CFDateGetAbsoluteTime(date); // no-warning
101  [((NSDate*) date) release];
102  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
103  return t;
104}
105
106
107NSDate* global_x;
108
109// Test to see if we supresss an error when we store the pointer
110// to a global.
111
112CFAbsoluteTime f3() {
113  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
114  CFDateRef date = CFDateCreate(0, t);  
115  [((NSDate*) date) retain];
116  CFRelease(date);
117  CFDateGetAbsoluteTime(date); // no-warning
118  global_x = (NSDate*) date;  
119  [((NSDate*) date) release];
120  t = CFDateGetAbsoluteTime(date);   // no-warning
121  return t;
122}
123
124//---------------------------------------------------------------------------
125// Test case 'f4' differs for region store and basic store.  See
126// retain-release-region-store.m and retain-release-basic-store.m.
127//---------------------------------------------------------------------------
128
129// Test a leak.
130
131CFAbsoluteTime f5(int x) {  
132  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
133  CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}}
134  
135  if (x)
136    CFRelease(date);
137  
138  return t;
139}
140
141// Test a leak involving the return.
142
143CFDateRef f6(int x) {  
144  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());  // expected-warning{{leak}}
145  CFRetain(date);
146  return date;
147}
148
149// Test a leak involving an overwrite.
150
151CFDateRef f7() {
152  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());  //expected-warning{{leak}}
153  CFRetain(date);
154  date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
155  return date;
156}
157
158// Generalization of Create rule.  MyDateCreate returns a CFXXXTypeRef, and
159// has the word create.
160CFDateRef MyDateCreate();
161
162CFDateRef f8() {
163  CFDateRef date = MyDateCreate(); // expected-warning{{leak}}
164  CFRetain(date);  
165  return date;
166}
167
168CFDateRef f9() {
169  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
170  int *p = 0;
171  // test that the checker assumes that CFDateCreate returns a non-null
172  // pointer
173  if (!date) *p = 1; // no-warning
174  return date;
175}
176
177// Handle DiskArbitration API:
178//
179// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/
180//
181void f10(io_service_t media, DADiskRef d, CFStringRef s) {
182  DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}}
183  if (disk) NSLog(@"ok");
184  
185  disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}}
186  if (disk) NSLog(@"ok");
187
188  CFDictionaryRef dict = DADiskCopyDescription(d);  // expected-warning{{leak}}
189  if (dict) NSLog(@"ok"); 
190  
191  disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}}
192  if (disk) NSLog(@"ok");
193    
194  DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault,   // expected-warning{{leak}}
195                                                kDAReturnSuccess, s);
196  if (dissenter) NSLog(@"ok");
197  
198  DASessionRef session = DASessionCreate(kCFAllocatorDefault);  // expected-warning{{leak}}
199  if (session) NSLog(@"ok");
200}
201
202// Test retain/release checker with CFString and CFMutableArray.
203void f11() {
204  // Create the array.
205  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
206
207  // Create a string.
208  CFStringRef s1 = CFStringCreateWithCString(0, "hello world",
209                                             kCFStringEncodingUTF8);
210
211  // Add the string to the array.
212  CFArrayAppendValue(A, s1);
213  
214  // Decrement the reference count.
215  CFRelease(s1); // no-warning
216  
217  // Get the string.  We don't own it.
218  s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
219  
220  // Release the array.
221  CFRelease(A); // no-warning
222  
223  // Release the string.  This is a bug.
224  CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
225}
226
227// PR 3337: Handle functions declared using typedefs.
228typedef CFTypeRef CREATEFUN();
229CREATEFUN MyCreateFun;
230
231void f12() {
232  CFTypeRef o = MyCreateFun(); // expected-warning {{leak}}
233}
234
235void f13_autorelease() {
236  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
237  [(id) A autorelease]; // no-warning
238}
239
240// This case exercises the logic where the leak site is the same as the allocation site.
241void f14_leakimmediately() {
242  CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
243}
244