retain-release.m revision 79b4f7d37530a1c41df26b6ac3a159f7cd6388d6
1//>>SLICER
2// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
3// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic-old-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// Test when we pass NULL to CFRetain/CFRelease.
394void f16(int x, CFTypeRef p) {
395  if (p)
396    return;
397
398  if (x) {
399    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
400  }
401  else {
402    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
403  }
404}
405
406// Test basic tracking of ivars associated with 'self'.  For the retain/release
407// checker we currently do not want to flag leaks associated with stores
408// of tracked objects to ivars.
409@interface SelfIvarTest : NSObject {
410  id myObj;
411}
412- (void)test_self_tracking;
413@end
414
415@implementation SelfIvarTest
416- (void)test_self_tracking {
417  myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
418}
419@end
420
421// Test return of non-owned objects in contexts where an owned object
422// is expected.
423@interface TestReturnNotOwnedWhenExpectedOwned
424- (NSString*)newString;
425@end
426
427@implementation TestReturnNotOwnedWhenExpectedOwned
428- (NSString*)newString {
429  NSString *s = [NSString stringWithUTF8String:"hello"];
430  return s; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
431}
432@end
433
434// <rdar://problem/6659160>
435int isFoo(char c);
436
437static void rdar_6659160(char *inkind, char *inname)
438{
439  // We currently expect that [NSObject alloc] cannot fail.  This
440  // will be a toggled flag in the future.  It can indeed return null, but
441  // Cocoa programmers generally aren't expected to reason about out-of-memory
442  // conditions.
443  NSString *kind = [[NSString alloc] initWithUTF8String:inkind];  // expected-warning{{leak}}
444  
445  // We do allow stringWithUTF8String to fail.  This isn't really correct, as
446  // far as returning 0.  In most error conditions it will throw an exception.
447  // If allocation fails it could return 0, but again this
448  // isn't expected.
449  NSString *name = [NSString stringWithUTF8String:inname];
450  if(!name)
451    return;
452
453  const char *kindC = 0;
454  const char *nameC = 0;
455  
456  // In both cases, we cannot reach a point down below where we
457  // dereference kindC or nameC with either being null.  This is because
458  // we assume that [NSObject alloc] doesn't fail and that we have the guard
459  // up above.
460  
461  if(kind)
462    kindC = [kind UTF8String];
463  if(name)
464    nameC = [name UTF8String];
465  if(!isFoo(kindC[0])) // expected-warning{{null}}
466    return;
467  if(!isFoo(nameC[0])) // no-warning
468    return;
469
470  [kind release];
471  [name release]; // expected-warning{{Incorrect decrement of the reference count}}
472}
473
474// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming
475//  conventions with respect to 'return'ing ownership.
476@interface PR3677: NSObject @end
477@implementation PR3677
478+ (id)allocWithZone:(NSZone *)inZone {
479  return [super allocWithZone:inZone];  // no-warning
480}
481@end
482
483// PR 3820 - Reason about calls to -dealloc
484void pr3820_DeallocInsteadOfRelease(void)
485{
486  id foo = [[NSString alloc] init]; // no-warning
487  [foo dealloc];
488  // foo is not leaked, since it has been deallocated.
489}
490
491void pr3820_ReleaseAfterDealloc(void)
492{
493  id foo = [[NSString alloc] init];
494  [foo dealloc];
495  [foo release];  // expected-warning{{used after it is release}}
496  // NSInternalInconsistencyException: message sent to deallocated object
497}
498
499void pr3820_DeallocAfterRelease(void)
500{
501  NSLog(@"\n\n[%s]", __FUNCTION__);
502  id foo = [[NSString alloc] init];
503  [foo release];
504  [foo dealloc]; // expected-warning{{used after it is released}}
505  // message sent to released object
506}
507
508// From <rdar://problem/6704930>.  The problem here is that 'length' binds to
509// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to
510// reason about '($0 - 1) > constant'.  As a temporary hack, we drop the value
511// of '($0 - 1)' and conjure a new symbol.
512void rdar6704930(unsigned char *s, unsigned int length) {
513  NSString* name = 0;
514  if (s != 0) {
515    if (length > 0) {
516      while (length > 0) {
517        if (*s == ':') {
518          ++s;
519          --length;
520          name = [[NSString alloc] init]; // no-warning
521          break;
522        }
523        ++s;
524        --length;
525      }
526      if ((length == 0) && (name != 0)) {
527        [name release];
528        name = 0;
529      }
530      if (length == 0) { // no ':' found -> use it all as name
531        name = [[NSString alloc] init]; // no-warning
532      }
533    }
534  }
535
536  if (name != 0) {
537    [name release];
538  }
539}
540
541//===----------------------------------------------------------------------===//
542// <rdar://problem/6833332>
543// One build of the analyzer accidentally stopped tracking the allocated
544// object after the 'retain'.
545//===----------------------------------------------------------------------===//
546
547@interface rdar_6833332 : NSObject <NSApplicationDelegate> {
548    NSWindow *window;
549}
550@property (nonatomic, retain) NSWindow *window;
551@end
552
553@implementation rdar_6833332
554@synthesize window;
555- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
556 NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}}
557
558 [dict setObject:@"foo" forKey:@"bar"];
559
560 NSLog(@"%@", dict);
561}
562- (void)dealloc {
563    [window release];
564    [super dealloc];
565}
566@end
567
568//===----------------------------------------------------------------------===//
569// <rdar://problem/6257780> clang checker fails to catch use-after-release
570//===----------------------------------------------------------------------===//
571                                 
572int rdar_6257780_Case1() {
573  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
574  NSArray *array = [NSArray array];
575  [array release]; // expected-warning{{Incorrect decrement of the reference count of an object is not owned at this point by the caller}}
576  [pool drain];
577  return 0;
578}
579
580//===----------------------------------------------------------------------===//
581// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs
582//===----------------------------------------------------------------------===//
583
584void rdar_6866843() {
585 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
586 NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init];
587 NSArray* array = [[NSArray alloc] init];
588 [dictionary setObject:array forKey:@"key"];
589 [array release];
590 // Using 'array' here should be fine
591 NSLog(@"array = %@\n", array); // no-warning
592 // Now the array is released
593 [dictionary release];
594 [pool drain];
595}
596
597
598//===----------------------------------------------------------------------===//
599// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects
600//===----------------------------------------------------------------------===//
601
602typedef CFTypeRef OtherRef;
603
604@interface RDar6877235 : NSObject {}
605- (CFTypeRef)_copyCFTypeRef;
606- (OtherRef)_copyOtherRef;
607@end
608
609@implementation RDar6877235
610- (CFTypeRef)_copyCFTypeRef {
611  return [[NSString alloc] init]; // no-warning
612}
613- (OtherRef)_copyOtherRef {
614  return [[NSString alloc] init]; // no-warning
615}
616@end
617
618//===----------------------------------------------------------------------===//
619//<rdar://problem/6320065> false positive - init method returns an object owned by caller
620//===----------------------------------------------------------------------===//
621
622@interface RDar6320065 : NSObject {
623  NSString *_foo;
624}
625- (id)initReturningNewClass;
626- (id)initReturningNewClassBad;
627- (id)initReturningNewClassBad2;
628@end
629
630@interface RDar6320065Subclass : RDar6320065
631@end
632
633@implementation RDar6320065
634- (id)initReturningNewClass {
635  [self release];
636  self = [[RDar6320065Subclass alloc] init]; // no-warning
637  return self;
638}
639- (id)initReturningNewClassBad {
640  [self release];
641  [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}}
642  return self;
643}
644- (id)initReturningNewClassBad2 {
645  [self release];
646  self = [[RDar6320065Subclass alloc] init];
647  return [self autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
648}
649
650@end
651
652@implementation RDar6320065Subclass
653@end
654
655int RDar6320065_test() {
656  RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning
657  [test release];
658  return 0;
659}
660
661//===----------------------------------------------------------------------===//
662// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a retained object
663//===----------------------------------------------------------------------===//
664
665@interface RDar6859457 : NSObject {}
666- (NSString*) NoCopyString;
667- (NSString*) noCopyString;
668@end
669
670@implementation RDar6859457 
671- (NSString*) NoCopyString { return [[NSString alloc] init]; } // no-warning
672- (NSString*) noCopyString { return [[NSString alloc] init]; } // no-warning
673@end
674
675void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) {
676  [x NoCopyString]; // expected-warning{{leak}}
677  [x noCopyString]; // expected-warning{{leak}}
678  [NSData dataWithBytesNoCopy:bytes length:dataLength];  // no-warning
679  [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning
680}
681
682//===----------------------------------------------------------------------===//
683// PR 4230 - an autorelease pool is not necessarily leaked during a premature
684//  return
685//===----------------------------------------------------------------------===//
686
687static void PR4230(void)
688{
689  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning
690  NSString *object = [[[NSString alloc] init] autorelease]; // no-warning
691  return;
692}
693
694//===----------------------------------------------------------------------===//
695// Method name that has a null IdentifierInfo* for its first selector slot.
696// This test just makes sure that we handle it.
697//===----------------------------------------------------------------------===//
698
699@interface TestNullIdentifier
700@end
701
702@implementation TestNullIdentifier
703+ (id):(int)x, ... {
704  return [[NSString alloc] init]; // expected-warning{{leak}}
705}
706@end
707
708//===----------------------------------------------------------------------===//
709// <rdar://problem/6893565> don't flag leaks for return types that cannot be 
710//                          determined to be CF types
711//===----------------------------------------------------------------------===//
712
713// We don't know if 'struct s6893565' represents a Core Foundation type, so
714// we shouldn't emit an error here.
715typedef struct s6893565* TD6893565;
716
717@interface RDar6893565 {}
718-(TD6893565)newThing;
719@end
720
721@implementation RDar6893565
722-(TD6893565)newThing {  
723  return (TD6893565) [[NSString alloc] init]; // no-warning
724}
725@end
726
727//===----------------------------------------------------------------------===//
728// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods
729//===----------------------------------------------------------------------===//
730
731void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context,
732                 NSString *str, CIImage *img, CGRect rect,
733                 CIFormat form, CGColorSpaceRef cs) {
734  [view createSnapshotImageOfType:str]; // expected-warning{{leak}}
735  [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}}
736  [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
737  [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
738}
739
740//===----------------------------------------------------------------------===//
741// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:]
742//                           misinterpreted by clang scan-build
743//===----------------------------------------------------------------------===//
744
745void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) {
746  [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}}
747}
748
749//===----------------------------------------------------------------------===//
750// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release 
751//                          checker
752//===----------------------------------------------------------------------===//
753
754void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options,  const char * bsdName) {  
755  IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}}
756}
757
758void IOServiceMatching_wrapper(const char * name) {
759  IOServiceMatching(name); // expected-warning{{leak}}
760}
761
762void IOServiceNameMatching_wrapper(const char * name) {
763  IOServiceNameMatching(name); // expected-warning{{leak}}
764}
765
766__attribute__((cf_returns_retained)) CFDictionaryRef CreateDict();
767
768void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType,
769  mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) {
770
771  CFDictionaryRef matching = CreateDict();
772  CFRelease(matching);
773  IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}}
774                           wakePort, reference, notification);
775}
776
777void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) {
778  IORegistryEntryIDMatching(entryID); // expected-warning{{leak}}
779}
780
781void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options,
782                                        const char * path) {
783  IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}}
784}
785
786void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) {
787  CFDictionaryRef matching = CreateDict();
788  IOServiceGetMatchingService(masterPort, matching);
789  CFRelease(matching); // expected-warning{{used after it is released}}
790}
791
792void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) {
793  CFDictionaryRef matching = CreateDict();
794  IOServiceGetMatchingServices(masterPort, matching, existing);
795  CFRelease(matching); // expected-warning{{used after it is released}}
796}
797
798void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, 
799  IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) {
800    
801  CFDictionaryRef matching = CreateDict();
802  IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification);
803  CFRelease(matching); // expected-warning{{used after it is released}}
804}
805
806//===----------------------------------------------------------------------===//
807// Tests of ownership attributes.
808//===----------------------------------------------------------------------===//
809
810typedef NSString* MyStringTy;
811
812@interface TestOwnershipAttr : NSObject
813- (NSString*) returnsAnOwnedString  __attribute__((ns_returns_retained)); // no-warning
814- (NSString*) returnsAnOwnedCFString  __attribute__((cf_returns_retained)); // no-warning
815- (MyStringTy) returnsAnOwnedTypedString __attribute__((ns_returns_retained)); // no-warning
816- (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}}
817@end
818
819static int ownership_attribute_doesnt_go_here __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}}
820
821void test_attr_1(TestOwnershipAttr *X) {
822  NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
823}
824
825void test_attr_1b(TestOwnershipAttr *X) {
826  NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
827}
828
829@interface MyClassTestCFAttr : NSObject {}
830- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
831- (CFDateRef) returnsCFRetainedAsCF __attribute__((cf_returns_retained));
832- (NSDate*) alsoReturnsRetained;
833- (CFDateRef) alsoReturnsRetainedAsCF;
834- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
835@end
836
837__attribute__((cf_returns_retained))
838CFDateRef returnsRetainedCFDate()  {
839  return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
840}
841
842@implementation MyClassTestCFAttr
843- (NSDate*) returnsCFRetained {
844  return (NSDate*) returnsRetainedCFDate(); // No leak.
845}
846
847- (CFDateRef) returnsCFRetainedAsCF {
848  return returnsRetainedCFDate(); // No leak.
849}
850
851
852- (NSDate*) alsoReturnsRetained {
853  return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
854}
855
856- (CFDateRef) alsoReturnsRetainedAsCF {
857  return returnsRetainedCFDate(); // expected-warning{{leak}}
858}
859
860
861- (NSDate*) returnsNSRetained {
862  return (NSDate*) returnsRetainedCFDate(); // no-warning
863}
864@end
865
866
867
868