retain-release.m revision 3148eb4a75f70f2636075c364d03104223f004d3
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@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
51@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
52@end    @interface NSObject <NSObject> {
53}
54@end  typedef float CGFloat;
55typedef double NSTimeInterval;
56@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
57@end      enum {
58NSObjCNoType = 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' }
59__attribute__((deprecated));
60typedef int kern_return_t;
61typedef kern_return_t mach_error_t;
62typedef mach_port_t io_object_t;
63typedef io_object_t io_service_t;
64typedef struct __DASession * DASessionRef;
65extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
66typedef struct __DADisk * DADiskRef;
67extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
68extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
69extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
70extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
71@interface NSAppleEventManager : NSObject {
72}
73@end enum {
74kDAReturnSuccess = 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 };
75typedef mach_error_t DAReturn;
76typedef const struct __DADissenter * DADissenterRef;
77extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
78
79//===----------------------------------------------------------------------===//
80// Test cases.
81//===----------------------------------------------------------------------===//
82
83CFAbsoluteTime f1() {
84  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
85  CFDateRef date = CFDateCreate(0, t);
86  CFRetain(date);
87  CFRelease(date);
88  CFDateGetAbsoluteTime(date); // no-warning
89  CFRelease(date);
90  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
91  return t;
92}
93
94CFAbsoluteTime f2() {
95  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
96  CFDateRef date = CFDateCreate(0, t);  
97  [((NSDate*) date) retain];
98  CFRelease(date);
99  CFDateGetAbsoluteTime(date); // no-warning
100  [((NSDate*) date) release];
101  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
102  return t;
103}
104
105
106NSDate* global_x;
107
108// Test to see if we supresss an error when we store the pointer
109// to a global.
110
111CFAbsoluteTime f3() {
112  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
113  CFDateRef date = CFDateCreate(0, t);  
114  [((NSDate*) date) retain];
115  CFRelease(date);
116  CFDateGetAbsoluteTime(date); // no-warning
117  global_x = (NSDate*) date;  
118  [((NSDate*) date) release];
119  t = CFDateGetAbsoluteTime(date);   // no-warning
120  return t;
121}
122
123//---------------------------------------------------------------------------
124// Test case 'f4' differs for region store and basic store.  See
125// retain-release-region-store.m and retain-release-basic-store.m.
126//---------------------------------------------------------------------------
127
128// Test a leak.
129
130CFAbsoluteTime f5(int x) {  
131  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
132  CFDateRef date = CFDateCreate(0, t);
133  
134  if (x)
135    CFRelease(date);
136  
137  return t; // expected-warning{{leak}}
138}
139
140// Test a leak involving the return.
141
142CFDateRef f6(int x) {  
143  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
144  CFRetain(date);
145  return date; // expected-warning{{leak}}
146}
147
148// Test a leak involving an overwrite.
149
150CFDateRef f7() {
151  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
152  CFRetain(date);
153  date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}}
154  return date;
155}
156
157// Generalization of Create rule.  MyDateCreate returns a CFXXXTypeRef, and
158// has the word create.
159CFDateRef MyDateCreate();
160
161CFDateRef f8() {
162  CFDateRef date = MyDateCreate();
163  CFRetain(date);  
164  return date; // expected-warning{{leak}}
165}
166
167CFDateRef f9() {
168  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
169  int *p = 0;
170  // test that the checker assumes that CFDateCreate returns a non-null
171  // pointer
172  if (!date) *p = 1; // no-warning
173  return date;
174}
175
176// Handle DiskArbitration API:
177//
178// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/
179//
180void f10(io_service_t media, DADiskRef d, CFStringRef s) {
181  DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello");
182  if (disk) NSLog(@"ok"); // expected-warning{{leak}}
183  
184  disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media);
185  if (disk) NSLog(@"ok"); // expected-warning{{leak}}
186
187  CFDictionaryRef dict = DADiskCopyDescription(d); 
188  if (dict) NSLog(@"ok"); // expected-warning{{leak}}
189  
190  disk = DADiskCopyWholeDisk(d);
191  if (disk) NSLog(@"ok"); // expected-warning{{leak}}
192    
193  DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault,
194                                                kDAReturnSuccess, s);
195  if (dissenter) NSLog(@"ok"); // expected-warning{{leak}}
196  
197  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
198  if (session) NSLog(@"ok"); // expected-warning{{leak}}
199}
200
201// Test retain/release checker with CFString and CFMutableArray.
202void f11() {
203  // Create the array.
204  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
205
206  // Create a string.
207  CFStringRef s1 = CFStringCreateWithCString(0, "hello world",
208                                             kCFStringEncodingUTF8);
209
210  // Add the string to the array.
211  CFArrayAppendValue(A, s1);
212  
213  // Decrement the reference count.
214  CFRelease(s1); // no-warning
215  
216  // Get the string.  We don't own it.
217  s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
218  
219  // Release the array.
220  CFRelease(A); // no-warning
221  
222  // Release the string.  This is a bug.
223  CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
224}
225
226// PR 3337: Handle functions declared using typedefs.
227typedef CFTypeRef CREATEFUN();
228CREATEFUN MyCreateFun;
229
230void f12() {
231  CFTypeRef o = MyCreateFun(); // expected-warning {{leak}}
232}
233