1// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify %s
2
3//===----------------------------------------------------------------------===//
4// The following code is reduced using delta-debugging from Mac OS X headers:
5//
6// #include <Cocoa/Cocoa.h>
7// #include <CoreFoundation/CoreFoundation.h>
8// #include <DiskArbitration/DiskArbitration.h>
9// #include <QuartzCore/QuartzCore.h>
10// #include <Quartz/Quartz.h>
11// #include <IOKit/IOKitLib.h>
12//
13// It includes the basic definitions for the test cases below.
14//===----------------------------------------------------------------------===//
15#define NULL 0
16#define nil ((id)0)
17typedef unsigned int __darwin_natural_t;
18typedef unsigned long uintptr_t;
19typedef unsigned int uint32_t;
20typedef unsigned long long uint64_t;
21typedef unsigned int UInt32;
22typedef signed long CFIndex;
23typedef CFIndex CFByteOrder;
24typedef struct {
25  CFIndex location;
26  CFIndex length;
27} CFRange;
28static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
29  CFRange range;
30  range.location = loc;
31  range.length = len;
32  return range;
33}
34typedef const void * CFTypeRef;
35typedef const struct __CFString * CFStringRef;
36typedef const struct __CFAllocator * CFAllocatorRef;
37extern const CFAllocatorRef kCFAllocatorDefault;
38extern CFTypeRef CFRetain(CFTypeRef cf);
39extern void CFRelease(CFTypeRef cf);
40typedef struct {
41}
42CFArrayCallBacks;
43extern const CFArrayCallBacks kCFTypeArrayCallBacks;
44typedef const struct __CFArray * CFArrayRef;
45typedef struct __CFArray * CFMutableArrayRef;
46extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
47extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
48extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
49typedef struct {
50}
51CFDictionaryKeyCallBacks;
52extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
53typedef struct {
54}
55CFDictionaryValueCallBacks;
56extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
57typedef const struct __CFDictionary * CFDictionaryRef;
58typedef struct __CFDictionary * CFMutableDictionaryRef;
59extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
60typedef UInt32 CFStringEncoding;
61enum {
62kCFStringEncodingMacRoman = 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  };
63extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
64typedef double CFTimeInterval;
65typedef CFTimeInterval CFAbsoluteTime;
66extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
67typedef const struct __CFDate * CFDateRef;
68extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
69extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
70typedef __darwin_natural_t natural_t;
71typedef natural_t mach_port_name_t;
72typedef mach_port_name_t mach_port_t;
73typedef int kern_return_t;
74typedef kern_return_t mach_error_t;
75enum {
76kCFNumberSInt8Type = 1,     kCFNumberSInt16Type = 2,     kCFNumberSInt32Type = 3,     kCFNumberSInt64Type = 4,     kCFNumberFloat32Type = 5,     kCFNumberFloat64Type = 6,      kCFNumberCharType = 7,     kCFNumberShortType = 8,     kCFNumberIntType = 9,     kCFNumberLongType = 10,     kCFNumberLongLongType = 11,     kCFNumberFloatType = 12,     kCFNumberDoubleType = 13,      kCFNumberCFIndexType = 14,      kCFNumberNSIntegerType = 15,     kCFNumberCGFloatType = 16,     kCFNumberMaxType = 16    };
77typedef CFIndex CFNumberType;
78typedef const struct __CFNumber * CFNumberRef;
79extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
80typedef const struct __CFAttributedString *CFAttributedStringRef;
81typedef struct __CFAttributedString *CFMutableAttributedStringRef;
82extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
83extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
84extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
85typedef signed char BOOL;
86typedef unsigned long NSUInteger;
87@class NSString, Protocol;
88extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
89typedef struct _NSZone NSZone;
90@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
91@protocol NSObject
92- (BOOL)isEqual:(id)object;
93- (id)retain;
94- (oneway void)release;
95- (Class)class;
96- (id)autorelease;
97- (id)init;
98@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
99@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
100@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
101@end
102@interface NSObject <NSObject> {}
103+ (id)allocWithZone:(NSZone *)zone;
104+ (id)alloc;
105+ (Class)class;
106- (void)dealloc;
107@end
108@interface NSObject (NSCoderMethods)
109- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
110@end
111extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
112typedef struct {
113}
114NSFastEnumerationState;
115@protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
116@end           @class NSString, NSDictionary;
117@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
118@end  @interface NSNumber : NSValue  - (char)charValue;
119- (id)initWithInt:(int)value;
120@end   @class NSString;
121@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
122@end  @interface NSArray (NSArrayCreation)  + (id)array;
123@end       @interface NSAutoreleasePool : NSObject {
124}
125- (void)drain;
126@end extern NSString * const NSBundleDidLoadNotification;
127typedef double NSTimeInterval;
128@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
129@end            typedef unsigned short unichar;
130@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
131- (NSUInteger)length;
132- (NSString *)stringByAppendingString:(NSString *)aString;
133- ( const char *)UTF8String;
134- (id)initWithUTF8String:(const char *)nullTerminatedCString;
135+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
136@end        @class NSString, NSURL, NSError;
137@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSUInteger)length;
138+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
139+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
140@end   @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
141@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
142@end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
143- (void)setObject:(id)anObject forKey:(id)aKey;
144@end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
145@end  typedef double CGFloat;
146struct CGSize {
147};
148typedef struct CGSize CGSize;
149struct CGRect {
150};
151typedef struct CGRect CGRect;
152typedef mach_port_t io_object_t;
153typedef char io_name_t[128];
154typedef io_object_t io_iterator_t;
155typedef io_object_t io_service_t;
156typedef struct IONotificationPort * IONotificationPortRef;
157typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
158io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
159kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
160kern_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));
161kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
162CFMutableDictionaryRef IOServiceMatching(  const char * name );
163CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
164CFMutableDictionaryRef IOBSDNameMatching(  mach_port_t masterPort,  uint32_t options,  const char * bsdName );
165CFMutableDictionaryRef IOOpenFirmwarePathMatching(  mach_port_t masterPort,  uint32_t options,  const char * path );
166CFMutableDictionaryRef IORegistryEntryIDMatching(  uint64_t entryID );
167typedef struct __DASession * DASessionRef;
168extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
169typedef struct __DADisk * DADiskRef;
170extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
171extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
172extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
173extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
174@interface NSTask : NSObject - (id)init;
175@end                    typedef struct CGColorSpace *CGColorSpaceRef;
176typedef struct CGImage *CGImageRef;
177typedef struct CGLayer *CGLayerRef;
178@interface NSResponder : NSObject <NSCoding> {
179}
180@end    @protocol NSAnimatablePropertyContainer      - (id)animator;
181@end  extern NSString *NSAnimationTriggerOrderIn ;
182@interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
183}
184@end @protocol NSValidatedUserInterfaceItem - (SEL)action;
185@end   @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
186@end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
187@interface NSApplication : NSResponder <NSUserInterfaceValidations> {
188}
189@end   enum {
190NSTerminateCancel = 0,         NSTerminateNow = 1,         NSTerminateLater = 2 };
191typedef NSUInteger NSApplicationTerminateReply;
192@protocol NSApplicationDelegate <NSObject> @optional        - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
193@end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
194@interface NSCell : NSObject <NSCopying, NSCoding> {
195}
196@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
197typedef struct {
198}
199CVTimeStamp;
200@interface CIImage : NSObject <NSCoding, NSCopying> {
201}
202typedef int CIFormat;
203@end  enum {
204kDAReturnSuccess = 0,     kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
205typedef mach_error_t DAReturn;
206typedef const struct __DADissenter * DADissenterRef;
207extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
208@interface CIContext: NSObject {
209}
210- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
211- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r     format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
212- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
213@end extern NSString* const QCRendererEventKey;
214@protocol QCCompositionRenderer - (NSDictionary*) attributes;
215@end   @interface QCRenderer : NSObject <QCCompositionRenderer> {
216}
217- (id) createSnapshotImageOfType:(NSString*)type;
218@end  extern NSString* const QCViewDidStartRenderingNotification;
219@interface QCView : NSView <QCCompositionRenderer> {
220}
221- (id) createSnapshotImageOfType:(NSString*)type;
222@end    enum {
223ICEXIFOrientation1 = 1,     ICEXIFOrientation2 = 2,     ICEXIFOrientation3 = 3,     ICEXIFOrientation4 = 4,     ICEXIFOrientation5 = 5,     ICEXIFOrientation6 = 6,     ICEXIFOrientation7 = 7,     ICEXIFOrientation8 = 8, };
224@class ICDevice;
225@protocol ICDeviceDelegate <NSObject>  @required      - (void)didRemoveDevice:(ICDevice*)device;
226@end extern NSString *const ICScannerStatusWarmingUp;
227@class ICScannerDevice;
228@protocol ICScannerDeviceDelegate <ICDeviceDelegate>  @optional       - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
229@end
230
231typedef long unsigned int __darwin_size_t;
232typedef __darwin_size_t size_t;
233typedef unsigned long CFTypeID;
234struct CGPoint {
235  CGFloat x;
236  CGFloat y;
237};
238typedef struct CGPoint CGPoint;
239typedef struct CGGradient *CGGradientRef;
240typedef uint32_t CGGradientDrawingOptions;
241extern CFTypeID CGGradientGetTypeID(void);
242extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef
243  space, const CGFloat components[], const CGFloat locations[], size_t count);
244extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space,
245  CFArrayRef colors, const CGFloat locations[]);
246extern CGGradientRef CGGradientRetain(CGGradientRef gradient);
247extern void CGGradientRelease(CGGradientRef gradient);
248typedef struct CGContext *CGContextRef;
249extern void CGContextDrawLinearGradient(CGContextRef context,
250    CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
251    CGGradientDrawingOptions options);
252extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
253
254@interface NSMutableArray : NSObject
255- (void)addObject:(id)object;
256+ (id)array;
257@end
258
259enum {
260    NSASCIIStringEncoding = 1,
261    NSNEXTSTEPStringEncoding = 2,
262    NSJapaneseEUCStringEncoding = 3,
263    NSUTF8StringEncoding = 4,
264    NSISOLatin1StringEncoding = 5,
265    NSSymbolStringEncoding = 6,
266    NSNonLossyASCIIStringEncoding = 7,
267};
268typedef struct __CFString * CFMutableStringRef;
269typedef NSUInteger NSStringEncoding;
270
271extern CFStringRef CFStringCreateWithCStringNoCopy(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding, CFAllocatorRef contentsDeallocator);
272
273typedef struct {
274  int ref;
275} isl_basic_map;
276
277//===----------------------------------------------------------------------===//
278// Test cases.
279//===----------------------------------------------------------------------===//
280
281void foo(id x) {
282  [x retain];
283}
284
285void bar(id x) {
286  [x release];
287}
288
289void test() {
290  NSString *s = [[NSString alloc] init]; // expected-warning {{Potential leak}}
291  foo(s);
292  foo(s);
293  bar(s);
294}
295
296void test_neg() {
297  NSString *s = [[NSString alloc] init]; // no-warning
298  foo(s);
299  foo(s);
300  bar(s);
301  bar(s);
302  bar(s);
303}
304
305__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap);
306void free(void *);
307
308void callee_side_parameter_checking_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) { // expected-warning {{Potential leak of an object}}
309}
310
311// As 'isl_basic_map_free' is annotated with 'rc_ownership_trusted_implementation', RetainCountChecker trusts its
312// implementation and doesn't analyze its body. If the annotation 'rc_ownership_trusted_implementation' is removed,
313// a leak warning is raised by RetainCountChecker as the analyzer is unable to detect a decrement in the reference
314// count of 'bmap' along the path in 'isl_basic_map_free' assuming the predicate of the second 'if' branch to be
315// true or assuming both the predicates in the function to be false.
316__attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *isl_basic_map_free(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
317  if (!bmap)
318    return NULL;
319
320  if (--bmap->ref > 0)
321    return NULL;
322
323  free(bmap);
324  return NULL;
325}
326
327// As 'isl_basic_map_copy' is annotated with 'rc_ownership_trusted_implementation', RetainCountChecker trusts its
328// implementation and doesn't analyze its body. If that annotation is removed, a 'use-after-release' warning might
329// be raised by RetainCountChecker as the pointer which is passed as an argument to this function and the pointer
330// which is returned from the function point to the same memory location.
331__attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_copy(isl_basic_map *bmap) {
332  if (!bmap)
333    return NULL;
334
335  bmap->ref++;
336  return bmap;
337}
338
339void test_use_after_release_with_trusted_implementation_annotate_attribute(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
340  // After this call, 'bmap' has a +1 reference count.
341  bmap = isl_basic_map_cow(bmap);
342  // After the call to 'isl_basic_map_copy', 'bmap' has a +1 reference count.
343  isl_basic_map *temp = isl_basic_map_cow(isl_basic_map_copy(bmap));
344  // After this call, 'bmap' has a +0 reference count.
345  isl_basic_map *temp2 = isl_basic_map_cow(bmap); // no-warning
346  isl_basic_map_free(temp2);
347  isl_basic_map_free(temp);
348}
349
350void test_leak_with_trusted_implementation_annotate_attribute(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
351  // After this call, 'bmap' has a +1 reference count.
352  bmap = isl_basic_map_cow(bmap); // no-warning
353  // After this call, 'bmap' has a +0 reference count.
354  isl_basic_map_free(bmap);
355}
356
357void callee_side_parameter_checking_incorrect_rc_decrement(isl_basic_map *bmap) {
358  isl_basic_map_free(bmap); // expected-warning {{Incorrect decrement of the reference count}}
359}
360
361__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_return_notowned_object(isl_basic_map *bmap) {
362  return bmap; // expected-warning {{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
363}
364
365__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_assign_consumed_parameter_leak_return(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
366  bmap1 = bmap2;
367  isl_basic_map_free(bmap2);
368  return bmap1;
369}
370
371__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_assign_consumed_parameter_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
372  bmap1 = bmap2;
373  isl_basic_map_free(bmap1);
374  return bmap2;
375}
376
377__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *error_path_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
378  bmap1 = isl_basic_map_cow(bmap1);
379  if (!bmap1 || !bmap2)
380    goto error;
381
382  isl_basic_map_free(bmap2);
383  return bmap1;
384error:
385  return isl_basic_map_free(bmap1);
386}
387
388//===----------------------------------------------------------------------===//
389// Test returning retained and not-retained values.
390//===----------------------------------------------------------------------===//
391
392// On return (intraprocedural), assume CF objects are leaked.
393CFStringRef test_return_ratained_CF(char *bytes) {
394  CFStringRef str;
395  return CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0); // expected-warning {{leak}}
396}
397
398// On return (intraprocedural), assume NSObjects are not leaked.
399id test_return_retained_NS() {
400  return [[NSString alloc] init]; // no-warning
401}
402
403void test_test_return_retained() {
404  id x = test_return_retained_NS(); // expected-warning {{leak}}
405  [x retain];
406  [x release];
407}
408
409//===----------------------------------------------------------------------===//
410// Test not applying "double effects" from inlining and RetainCountChecker summaries.
411// If we inline a call, we should already see its retain/release semantics.
412//===----------------------------------------------------------------------===//
413
414__attribute__((cf_returns_retained)) CFStringRef test_return_inline(CFStringRef x) {
415  CFRetain(x);
416  return x;
417}
418
419void test_test_return_inline(char *bytes) {
420  CFStringRef str = CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0);
421  // After this call, 'str' really has +2 reference count.
422  CFStringRef str2 = test_return_inline(str);
423  // After this call, 'str' really has a +1 reference count.
424  CFRelease(str);
425  // After this call, 'str2' and 'str' has a +0 reference count.
426  CFRelease(str2);
427}
428
429void test_test_return_inline_2(char *bytes) {
430  CFStringRef str = CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0); // expected-warning {{leak}}
431  // After this call, 'str' really has +2 reference count.
432  CFStringRef str2 = test_return_inline(str);
433  // After this call, 'str' really has a +1 reference count.
434  CFRelease(str);
435}
436
437extern CFStringRef getString(void);
438CFStringRef testCovariantReturnType(void) __attribute__((cf_returns_retained));
439
440void usetestCovariantReturnType() {
441  CFStringRef S = ((void*)0);
442  S = testCovariantReturnType();
443  if (S)
444    CFRelease(S);
445}
446
447CFStringRef testCovariantReturnType() {
448  CFStringRef Str = ((void*)0);
449  Str = getString();
450  if (Str) {
451    CFRetain(Str);
452  }
453  return Str;
454}
455
456// Test that we reanalyze ObjC methods which have been inlined. When reanalyzing
457// them, make sure we inline very small functions.
458id returnInputParam(id x) {
459  return x;
460}
461
462@interface MyClass : NSObject
463- (id)test_reanalyze_as_top_level;
464- (void)test_inline_tiny_when_reanalyzing;
465- (void)inline_test_reanalyze_as_top_level;
466@end
467
468@implementation MyClass
469- (void)test_inline_tiny_when_reanalyzing {
470  id x = [[NSString alloc] init]; // no-warning
471  x = returnInputParam(x);
472  [x release];
473}
474
475- (id)test_reanalyze_as_top_level {
476  // This method does not follow naming conventions, so a warning will be
477  // reported when it is reanalyzed at top level.
478  return [[NSString alloc] init]; // expected-warning {{leak}}
479}
480
481- (void)inline_test_reanalyze_as_top_level {
482  id x = [self test_reanalyze_as_top_level];
483  [x release];
484  [self test_inline_tiny_when_reanalyzing];
485}
486@end
487
488// Original problem: rdar://problem/50739539
489@interface MyClassThatLeaksDuringInit : NSObject
490
491+ (MyClassThatLeaksDuringInit *)getAnInstance1;
492+ (MyClassThatLeaksDuringInit *)getAnInstance2;
493
494@end
495
496@implementation MyClassThatLeaksDuringInit
497
498+ (MyClassThatLeaksDuringInit *)getAnInstance1 {
499  return [[[MyClassThatLeaksDuringInit alloc] init] autorelease]; // expected-warning{{leak}}
500}
501
502+ (MyClassThatLeaksDuringInit *)getAnInstance2 {
503  return [[[[self class] alloc] init] autorelease]; // expected-warning{{leak}}
504}
505
506- (instancetype)init {
507  if (1) {
508    return nil;
509  }
510
511  if (nil != (self = [super init])) {
512  }
513  return self;
514}
515
516@end
517