retain-release.m revision e1cea75e70d76f55157749a7bcad319050492945
1//>>SLICER
2// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
3// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic-new-cast -verify %s &&
4// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
5
6//===----------------------------------------------------------------------===//
7// The following code is reduced using delta-debugging from Mac OS X headers:
8//
9// #include <Cocoa/Cocoa.h>
10// #include <CoreFoundation/CoreFoundation.h>
11// #include <DiskArbitration/DiskArbitration.h>
12// #include <QuartzCore/QuartzCore.h>
13// #include <Quartz/Quartz.h>
14// #include <IOKit/IOKitLib.h>
15//
16// It includes the basic definitions for the test cases below.
17//===----------------------------------------------------------------------===//
18
19typedef unsigned int __darwin_natural_t;
20typedef unsigned long uintptr_t;
21typedef unsigned int uint32_t;
22typedef unsigned long long uint64_t;
23typedef unsigned int UInt32;
24typedef signed long CFIndex;
25typedef const void * CFTypeRef;
26typedef const struct __CFString * CFStringRef;
27typedef const struct __CFAllocator * CFAllocatorRef;
28extern const CFAllocatorRef kCFAllocatorDefault;
29extern CFTypeRef CFRetain(CFTypeRef cf);
30extern void CFRelease(CFTypeRef cf);
31typedef struct {
32}
33CFArrayCallBacks;
34extern const CFArrayCallBacks kCFTypeArrayCallBacks;
35typedef const struct __CFArray * CFArrayRef;
36typedef struct __CFArray * CFMutableArrayRef;
37extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
38extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
39extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
40typedef const struct __CFDictionary * CFDictionaryRef;
41typedef struct __CFDictionary * CFMutableDictionaryRef;
42typedef UInt32 CFStringEncoding;
43enum {
44kCFStringEncodingMacRoman = 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  };
45extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
46typedef double CFTimeInterval;
47typedef CFTimeInterval CFAbsoluteTime;
48extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
49typedef const struct __CFDate * CFDateRef;
50extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
51extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
52typedef __darwin_natural_t natural_t;
53typedef natural_t mach_port_name_t;
54typedef mach_port_name_t mach_port_t;
55typedef int kern_return_t;
56typedef kern_return_t mach_error_t;
57typedef signed char BOOL;
58typedef unsigned long NSUInteger;
59@class NSString, Protocol;
60extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
61typedef struct _NSZone NSZone;
62@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
63@protocol NSObject  - (BOOL)isEqual:(id)object;
64- (id)retain;
65- (oneway void)release;
66- (id)autorelease;
67@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
68@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
69@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
70@end    @interface NSObject <NSObject> {
71}
72+ (id)allocWithZone:(NSZone *)zone;
73+ (id)alloc;
74- (void)dealloc;
75@end      extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
76typedef struct {
77}
78NSFastEnumerationState;
79@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
80@end   @class NSString;
81@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
82@end  @interface NSArray (NSArrayCreation)  + (id)array;
83@end       @interface NSAutoreleasePool : NSObject {
84}
85- (void)drain;
86@end extern NSString * const NSBundleDidLoadNotification;
87typedef double NSTimeInterval;
88@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
89@end            typedef unsigned short unichar;
90@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
91- ( const char *)UTF8String;
92- (id)initWithUTF8String:(const char *)nullTerminatedCString;
93+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
94@end       @class NSString, NSData;
95@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSUInteger)length;
96+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
97+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
98@end             @class NSString;
99@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
100@end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
101- (void)setObject:(id)anObject forKey:(id)aKey;
102@end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
103@end  typedef double CGFloat;
104struct CGSize {
105};
106typedef struct CGSize CGSize;
107struct CGRect {
108};
109typedef struct CGRect CGRect;
110@protocol NSLocking  - (void)lock;
111- (id)init;
112@end @class NSURLAuthenticationChallenge;
113typedef mach_port_t io_object_t;
114typedef char io_name_t[128];
115typedef io_object_t io_iterator_t;
116typedef io_object_t io_service_t;
117typedef struct IONotificationPort * IONotificationPortRef;
118typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
119io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
120kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
121kern_return_t IOServiceAddNotification(  mach_port_t masterPort,  const io_name_t notificationType,  CFDictionaryRef matching,  mach_port_t wakePort,  uintptr_t reference,  io_iterator_t * notification ) __attribute__((deprecated));
122kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
123CFMutableDictionaryRef IOServiceMatching(  const char * name );
124CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
125CFMutableDictionaryRef IOBSDNameMatching(  mach_port_t masterPort,  uint32_t options,  const char * bsdName );
126CFMutableDictionaryRef IOOpenFirmwarePathMatching(  mach_port_t masterPort,  uint32_t options,  const char * path );
127CFMutableDictionaryRef IORegistryEntryIDMatching(  uint64_t entryID );
128typedef struct __DASession * DASessionRef;
129extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
130typedef struct __DADisk * DADiskRef;
131extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
132extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
133extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
134extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
135typedef struct CGColorSpace *CGColorSpaceRef;
136typedef struct CGImage *CGImageRef;
137  typedef struct CGLayer *CGLayerRef;
138           @class NSArray, NSError, NSEvent, NSMenu, NSUndoManager, NSWindow;
139@interface NSResponder : NSObject <NSCoding> {
140}
141@end    @protocol NSAnimatablePropertyContainer      - (id)animator;
142@end  extern NSString *NSAnimationTriggerOrderIn ;
143@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
144struct __VFlags2 {
145}
146_vFlags2;
147}
148@end   extern NSString * const NSFullScreenModeAllScreens;
149@protocol NSChangeSpelling - (void)changeSpelling:(id)sender;
150@end      @protocol NSIgnoreMisspelledWords - (void)ignoreSpelling:(id)sender;
151@end  @class NSColor, NSFont, NSNotification;
152@interface NSText : NSView <NSChangeSpelling, NSIgnoreMisspelledWords> {
153}
154@end @protocol NSValidatedUserInterfaceItem - (SEL)action;
155@end   @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
156@end @class NSArray, NSError, NSImage, NSView, NSNotificationCenter, NSURL, NSScreen, NSRunningApplication;
157@interface NSApplication : NSResponder <NSUserInterfaceValidations> {
158}
159@end   enum {
160NSTerminateCancel = 0,         NSTerminateNow = 1,         NSTerminateLater = 2 };
161typedef NSUInteger NSApplicationTerminateReply;
162@protocol NSApplicationDelegate <NSObject> @optional        - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
163@end    enum {
164}
165_CFlags;
166@interface CIImage : NSObject <NSCoding, NSCopying> {
167}
168typedef int CIFormat;
169@end  enum {
170kDAReturnSuccess = 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 };
171typedef mach_error_t DAReturn;
172typedef const struct __DADissenter * DADissenterRef;
173extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
174@interface CIContext: NSObject {
175}
176- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
177- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r     format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
178- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
179@end @class NSURL;
180@protocol QCCompositionRenderer - (NSDictionary*) attributes;
181@end   @interface QCRenderer : NSObject <QCCompositionRenderer> {
182}
183- (id) createSnapshotImageOfType:(NSString*)type;
184@end  extern NSString* const QCViewDidStartRenderingNotification;
185@interface QCView : NSView <QCCompositionRenderer> {
186}
187- (id) createSnapshotImageOfType:(NSString*)type;
188@end    enum {
189ICEXIFOrientation1 = 1,     ICEXIFOrientation2 = 2,     ICEXIFOrientation3 = 3,     ICEXIFOrientation4 = 4,     ICEXIFOrientation5 = 5,     ICEXIFOrientation6 = 6,     ICEXIFOrientation7 = 7,     ICEXIFOrientation8 = 8, };
190@class ICDevice;
191@protocol ICDeviceDelegate <NSObject>  @required      - (void)didRemoveDevice:(ICDevice*)device;
192@end  @class ICCameraDevice;
193@class ICScannerDevice;
194@protocol ICScannerDeviceDelegate <ICDeviceDelegate>  @optional       - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
195@end
196  
197//===----------------------------------------------------------------------===//
198// Test cases.
199//===----------------------------------------------------------------------===//
200
201CFAbsoluteTime f1() {
202  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
203  CFDateRef date = CFDateCreate(0, t);
204  CFRetain(date);
205  CFRelease(date);
206  CFDateGetAbsoluteTime(date); // no-warning
207  CFRelease(date);
208  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
209  return t;
210}
211
212CFAbsoluteTime f2() {
213  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
214  CFDateRef date = CFDateCreate(0, t);  
215  [((NSDate*) date) retain];
216  CFRelease(date);
217  CFDateGetAbsoluteTime(date); // no-warning
218  [((NSDate*) date) release];
219  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
220  return t;
221}
222
223
224NSDate* global_x;
225
226// Test to see if we supresss an error when we store the pointer
227// to a global.
228
229CFAbsoluteTime f3() {
230  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
231  CFDateRef date = CFDateCreate(0, t);  
232  [((NSDate*) date) retain];
233  CFRelease(date);
234  CFDateGetAbsoluteTime(date); // no-warning
235  global_x = (NSDate*) date;  
236  [((NSDate*) date) release];
237  t = CFDateGetAbsoluteTime(date);   // no-warning
238  return t;
239}
240
241//---------------------------------------------------------------------------
242// Test case 'f4' differs for region store and basic store.  See
243// retain-release-region-store.m and retain-release-basic-store.m.
244//---------------------------------------------------------------------------
245
246// Test a leak.
247
248CFAbsoluteTime f5(int x) {  
249  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
250  CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}}
251  
252  if (x)
253    CFRelease(date);
254  
255  return t;
256}
257
258// Test a leak involving the return.
259
260CFDateRef f6(int x) {  
261  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());  // expected-warning{{leak}}
262  CFRetain(date);
263  return date;
264}
265
266// Test a leak involving an overwrite.
267
268CFDateRef f7() {
269  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());  //expected-warning{{leak}}
270  CFRetain(date);
271  date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
272  return date;
273}
274
275// Generalization of Create rule.  MyDateCreate returns a CFXXXTypeRef, and
276// has the word create.
277CFDateRef MyDateCreate();
278
279CFDateRef f8() {
280  CFDateRef date = MyDateCreate(); // expected-warning{{leak}}
281  CFRetain(date);  
282  return date;
283}
284
285CFDateRef f9() {
286  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
287  int *p = 0;
288  // When allocations fail, CFDateCreate can return null.
289  if (!date) *p = 1; // expected-warning{{null}}
290  return date;
291}
292
293// Handle DiskArbitration API:
294//
295// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/
296//
297void f10(io_service_t media, DADiskRef d, CFStringRef s) {
298  DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}}
299  if (disk) NSLog(@"ok");
300  
301  disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}}
302  if (disk) NSLog(@"ok");
303
304  CFDictionaryRef dict = DADiskCopyDescription(d);  // expected-warning{{leak}}
305  if (dict) NSLog(@"ok"); 
306  
307  disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}}
308  if (disk) NSLog(@"ok");
309    
310  DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault,   // expected-warning{{leak}}
311                                                kDAReturnSuccess, s);
312  if (dissenter) NSLog(@"ok");
313  
314  DASessionRef session = DASessionCreate(kCFAllocatorDefault);  // expected-warning{{leak}}
315  if (session) NSLog(@"ok");
316}
317
318// Test retain/release checker with CFString and CFMutableArray.
319void f11() {
320  // Create the array.
321  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
322
323  // Create a string.
324  CFStringRef s1 = CFStringCreateWithCString(0, "hello world",
325                                             kCFStringEncodingUTF8);
326
327  // Add the string to the array.
328  CFArrayAppendValue(A, s1);
329  
330  // Decrement the reference count.
331  CFRelease(s1); // no-warning
332  
333  // Get the string.  We don't own it.
334  s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
335  
336  // Release the array.
337  CFRelease(A); // no-warning
338  
339  // Release the string.  This is a bug.
340  CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
341}
342
343// PR 3337: Handle functions declared using typedefs.
344typedef CFTypeRef CREATEFUN();
345CREATEFUN MyCreateFun;
346
347void f12() {
348  CFTypeRef o = MyCreateFun(); // expected-warning {{leak}}
349}
350
351void f13_autorelease() {
352  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
353  [(id) A autorelease]; // no-warning
354}
355
356void f13_autorelease_b() {
357  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
358  [(id) A autorelease];
359  [(id) A autorelease]; // expected-warning{{Object sent -autorelease too many times}}
360}
361
362CFMutableArrayRef f13_autorelease_c() {
363  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
364  [(id) A autorelease];
365  [(id) A autorelease]; 
366  return A; // expected-warning{{Object sent -autorelease too many times}}
367}
368
369CFMutableArrayRef f13_autorelease_d() {
370  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
371  [(id) A autorelease];
372  [(id) A autorelease]; 
373  CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}}
374  CFRelease(B); // no-warning
375}
376
377
378// This case exercises the logic where the leak site is the same as the allocation site.
379void f14_leakimmediately() {
380  CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
381}
382
383// Test that we track an allocated object beyond the point where the *name*
384// of the variable storing the reference is no longer live.
385void f15() {
386  // Create the array.
387  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
388  CFMutableArrayRef *B = &A;
389  // At this point, the name 'A' is no longer live.
390  CFRelease(*B);  // no-warning
391}
392
393
394// Test basic tracking of ivars associated with 'self'.  For the retain/release
395// checker we currently do not want to flag leaks associated with stores
396// of tracked objects to ivars.
397@interface SelfIvarTest : NSObject {
398  id myObj;
399}
400- (void)test_self_tracking;
401@end
402
403@implementation SelfIvarTest
404- (void)test_self_tracking {
405  myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
406}
407@end
408
409// Test return of non-owned objects in contexts where an owned object
410// is expected.
411@interface TestReturnNotOwnedWhenExpectedOwned
412- (NSString*)newString;
413@end
414
415@implementation TestReturnNotOwnedWhenExpectedOwned
416- (NSString*)newString {
417  NSString *s = [NSString stringWithUTF8String:"hello"];
418  return s; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
419}
420@end
421
422// <rdar://problem/6659160>
423int isFoo(char c);
424
425static void rdar_6659160(char *inkind, char *inname)
426{
427  // We currently expect that [NSObject alloc] cannot fail.  This
428  // will be a toggled flag in the future.  It can indeed return null, but
429  // Cocoa programmers generally aren't expected to reason about out-of-memory
430  // conditions.
431  NSString *kind = [[NSString alloc] initWithUTF8String:inkind];  // expected-warning{{leak}}
432  
433  // We do allow stringWithUTF8String to fail.  This isn't really correct, as
434  // far as returning 0.  In most error conditions it will throw an exception.
435  // If allocation fails it could return 0, but again this
436  // isn't expected.
437  NSString *name = [NSString stringWithUTF8String:inname];
438  if(!name)
439    return;
440
441  const char *kindC = 0;
442  const char *nameC = 0;
443  
444  // In both cases, we cannot reach a point down below where we
445  // dereference kindC or nameC with either being null.  This is because
446  // we assume that [NSObject alloc] doesn't fail and that we have the guard
447  // up above.
448  
449  if(kind)
450    kindC = [kind UTF8String];
451  if(name)
452    nameC = [name UTF8String];
453  if(!isFoo(kindC[0])) // expected-warning{{null}}
454    return;
455  if(!isFoo(nameC[0])) // no-warning
456    return;
457
458  [kind release];
459  [name release]; // expected-warning{{Incorrect decrement of the reference count}}
460}
461
462// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming
463//  conventions with respect to 'return'ing ownership.
464@interface PR3677: NSObject @end
465@implementation PR3677
466+ (id)allocWithZone:(NSZone *)inZone {
467  return [super allocWithZone:inZone];  // no-warning
468}
469@end
470
471// PR 3820 - Reason about calls to -dealloc
472void pr3820_DeallocInsteadOfRelease(void)
473{
474  id foo = [[NSString alloc] init]; // no-warning
475  [foo dealloc];
476  // foo is not leaked, since it has been deallocated.
477}
478
479void pr3820_ReleaseAfterDealloc(void)
480{
481  id foo = [[NSString alloc] init];
482  [foo dealloc];
483  [foo release];  // expected-warning{{used after it is release}}
484  // NSInternalInconsistencyException: message sent to deallocated object
485}
486
487void pr3820_DeallocAfterRelease(void)
488{
489  NSLog(@"\n\n[%s]", __FUNCTION__);
490  id foo = [[NSString alloc] init];
491  [foo release];
492  [foo dealloc]; // expected-warning{{used after it is released}}
493  // message sent to released object
494}
495
496// From <rdar://problem/6704930>.  The problem here is that 'length' binds to
497// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to
498// reason about '($0 - 1) > constant'.  As a temporary hack, we drop the value
499// of '($0 - 1)' and conjure a new symbol.
500void rdar6704930(unsigned char *s, unsigned int length) {
501  NSString* name = 0;
502  if (s != 0) {
503    if (length > 0) {
504      while (length > 0) {
505        if (*s == ':') {
506          ++s;
507          --length;
508          name = [[NSString alloc] init]; // no-warning
509          break;
510        }
511        ++s;
512        --length;
513      }
514      if ((length == 0) && (name != 0)) {
515        [name release];
516        name = 0;
517      }
518      if (length == 0) { // no ':' found -> use it all as name
519        name = [[NSString alloc] init]; // no-warning
520      }
521    }
522  }
523
524  if (name != 0) {
525    [name release];
526  }
527}
528
529//===----------------------------------------------------------------------===//
530// <rdar://problem/6833332>
531// One build of the analyzer accidentally stopped tracking the allocated
532// object after the 'retain'.
533//===----------------------------------------------------------------------===//
534
535@interface rdar_6833332 : NSObject <NSApplicationDelegate> {
536    NSWindow *window;
537}
538@property (nonatomic, retain) NSWindow *window;
539@end
540
541@implementation rdar_6833332
542@synthesize window;
543- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
544 NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}}
545
546 [dict setObject:@"foo" forKey:@"bar"];
547
548 NSLog(@"%@", dict);
549}
550- (void)dealloc {
551    [window release];
552    [super dealloc];
553}
554@end
555
556//===----------------------------------------------------------------------===//
557// <rdar://problem/6257780> clang checker fails to catch use-after-release
558//===----------------------------------------------------------------------===//
559                                 
560int rdar_6257780_Case1() {
561  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
562  NSArray *array = [NSArray array];
563  [array release]; // expected-warning{{Incorrect decrement of the reference count of an object is not owned at this point by the caller}}
564  [pool drain];
565  return 0;
566}
567
568//===----------------------------------------------------------------------===//
569// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs
570//===----------------------------------------------------------------------===//
571
572void rdar_6866843() {
573 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
574 NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init];
575 NSArray* array = [[NSArray alloc] init];
576 [dictionary setObject:array forKey:@"key"];
577 [array release];
578 // Using 'array' here should be fine
579 NSLog(@"array = %@\n", array); // no-warning
580 // Now the array is released
581 [dictionary release];
582 [pool drain];
583}
584
585
586//===----------------------------------------------------------------------===//
587// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects
588//===----------------------------------------------------------------------===//
589
590typedef CFTypeRef OtherRef;
591
592@interface RDar6877235 : NSObject {}
593- (CFTypeRef)_copyCFTypeRef;
594- (OtherRef)_copyOtherRef;
595@end
596
597@implementation RDar6877235
598- (CFTypeRef)_copyCFTypeRef {
599  return [[NSString alloc] init]; // no-warning
600}
601- (OtherRef)_copyOtherRef {
602  return [[NSString alloc] init]; // no-warning
603}
604@end
605
606//===----------------------------------------------------------------------===//
607//<rdar://problem/6320065> false positive - init method returns an object owned by caller
608//===----------------------------------------------------------------------===//
609
610@interface RDar6320065 : NSObject {
611  NSString *_foo;
612}
613- (id)initReturningNewClass;
614- (id)initReturningNewClassBad;
615- (id)initReturningNewClassBad2;
616@end
617
618@interface RDar6320065Subclass : RDar6320065
619@end
620
621@implementation RDar6320065
622- (id)initReturningNewClass {
623  [self release];
624  self = [[RDar6320065Subclass alloc] init]; // no-warning
625  return self;
626}
627- (id)initReturningNewClassBad {
628  [self release];
629  [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}}
630  return self;
631}
632- (id)initReturningNewClassBad2 {
633  [self release];
634  self = [[RDar6320065Subclass alloc] init];
635  return [self autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
636}
637
638@end
639
640@implementation RDar6320065Subclass
641@end
642
643int RDar6320065_test() {
644  RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning
645  [test release];
646  return 0;
647}
648
649//===----------------------------------------------------------------------===//
650// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a retained object
651//===----------------------------------------------------------------------===//
652
653@interface RDar6859457 : NSObject {}
654- (NSString*) NoCopyString;
655- (NSString*) noCopyString;
656@end
657
658@implementation RDar6859457 
659- (NSString*) NoCopyString { return [[NSString alloc] init]; } // no-warning
660- (NSString*) noCopyString { return [[NSString alloc] init]; } // no-warning
661@end
662
663void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) {
664  [x NoCopyString]; // expected-warning{{leak}}
665  [x noCopyString]; // expected-warning{{leak}}
666  [NSData dataWithBytesNoCopy:bytes length:dataLength];  // no-warning
667  [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning
668}
669
670//===----------------------------------------------------------------------===//
671// PR 4230 - an autorelease pool is not necessarily leaked during a premature
672//  return
673//===----------------------------------------------------------------------===//
674
675static void PR4230(void)
676{
677  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning
678  NSString *object = [[[NSString alloc] init] autorelease]; // no-warning
679  return;
680}
681
682//===----------------------------------------------------------------------===//
683// Method name that has a null IdentifierInfo* for its first selector slot.
684// This test just makes sure that we handle it.
685//===----------------------------------------------------------------------===//
686
687@interface TestNullIdentifier
688@end
689
690@implementation TestNullIdentifier
691+ (id):(int)x, ... {
692  return [[NSString alloc] init]; // expected-warning{{leak}}
693}
694@end
695
696//===----------------------------------------------------------------------===//
697// <rdar://problem/6893565> don't flag leaks for return types that cannot be 
698//                          determined to be CF types
699//===----------------------------------------------------------------------===//
700
701// We don't know if 'struct s6893565' represents a Core Foundation type, so
702// we shouldn't emit an error here.
703typedef struct s6893565* TD6893565;
704
705@interface RDar6893565 {}
706-(TD6893565)newThing;
707@end
708
709@implementation RDar6893565
710-(TD6893565)newThing {  
711  return (TD6893565) [[NSString alloc] init]; // no-warning
712}
713@end
714
715//===----------------------------------------------------------------------===//
716// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods
717//===----------------------------------------------------------------------===//
718
719void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context,
720                 NSString *str, CIImage *img, CGRect rect,
721                 CIFormat form, CGColorSpaceRef cs) {
722  [view createSnapshotImageOfType:str]; // expected-warning{{leak}}
723  [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}}
724  [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
725  [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
726}
727
728//===----------------------------------------------------------------------===//
729// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:]
730//                           misinterpreted by clang scan-build
731//===----------------------------------------------------------------------===//
732
733void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) {
734  [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}}
735}
736
737//===----------------------------------------------------------------------===//
738// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release 
739//                          checker
740//===----------------------------------------------------------------------===//
741
742void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options,  const char * bsdName) {  
743  IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}}
744}
745
746void IOServiceMatching_wrapper(const char * name) {
747  IOServiceMatching(name); // expected-warning{{leak}}
748}
749
750void IOServiceNameMatching_wrapper(const char * name) {
751  IOServiceNameMatching(name); // expected-warning{{leak}}
752}
753
754__attribute__((cf_returns_retained)) CFDictionaryRef CreateDict();
755
756void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType,
757  mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) {
758
759  CFDictionaryRef matching = CreateDict();
760  CFRelease(matching);
761  IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}}
762                           wakePort, reference, notification);
763}
764
765void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) {
766  IORegistryEntryIDMatching(entryID); // expected-warning{{leak}}
767}
768
769void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options,
770                                        const char * path) {
771  IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}}
772}
773
774void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) {
775  CFDictionaryRef matching = CreateDict();
776  IOServiceGetMatchingService(masterPort, matching);
777  CFRelease(matching); // expected-warning{{used after it is released}}
778}
779
780void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) {
781  CFDictionaryRef matching = CreateDict();
782  IOServiceGetMatchingServices(masterPort, matching, existing);
783  CFRelease(matching); // expected-warning{{used after it is released}}
784}
785
786void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, 
787  IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) {
788    
789  CFDictionaryRef matching = CreateDict();
790  IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification);
791  CFRelease(matching); // expected-warning{{used after it is released}}
792}
793
794//===----------------------------------------------------------------------===//
795// Tests of ownership attributes.
796//===----------------------------------------------------------------------===//
797
798typedef NSString* MyStringTy;
799
800@interface TestOwnershipAttr : NSObject
801- (NSString*) returnsAnOwnedString  __attribute__((ns_returns_retained)); // no-warning
802- (NSString*) returnsAnOwnedCFString  __attribute__((cf_returns_retained)); // no-warning
803- (MyStringTy) returnsAnOwnedTypedString __attribute__((ns_returns_retained)); // no-warning
804- (int) returnsAnOwnedInt __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}}
805@end
806
807static int ownership_attribute_doesnt_go_here __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}}
808
809void test_attr_1(TestOwnershipAttr *X) {
810  NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
811}
812
813void test_attr_1b(TestOwnershipAttr *X) {
814  NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
815}
816
817@interface MyClassTestCFAttr : NSObject {}
818- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
819- (CFDateRef) returnsCFRetainedAsCF __attribute__((cf_returns_retained));
820- (NSDate*) alsoReturnsRetained;
821- (CFDateRef) alsoReturnsRetainedAsCF;
822- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
823@end
824
825__attribute__((cf_returns_retained))
826CFDateRef returnsRetainedCFDate()  {
827  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
828}
829
830@implementation MyClassTestCFAttr
831- (NSDate*) returnsCFRetained {
832  return (NSDate*) returnsRetainedCFDate(); // No leak.
833}
834
835- (CFDateRef) returnsCFRetainedAsCF {
836  return returnsRetainedCFDate(); // No leak.
837}
838
839
840- (NSDate*) alsoReturnsRetained {
841  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
842}
843
844- (CFDateRef) alsoReturnsRetainedAsCF {
845  return returnsRetainedCFDate(); // expected-warning{{leak}}
846}
847
848
849- (NSDate*) returnsNSRetained {
850  return (NSDate*) returnsRetainedCFDate(); // no-warning
851}
852@end
853
854
855
856