Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify -Wno-objc-root-class %s
      2 
      3 //===----------------------------------------------------------------------===//
      4 // Header stuff.
      5 //===----------------------------------------------------------------------===//
      6 
      7 typedef unsigned int __darwin_natural_t;
      8 typedef unsigned long uintptr_t;
      9 typedef unsigned int uint32_t;
     10 typedef unsigned long long uint64_t;
     11 typedef unsigned int UInt32;
     12 typedef signed long CFIndex;
     13 typedef struct {
     14     CFIndex location;
     15     CFIndex length;
     16 } CFRange;
     17 static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
     18     CFRange range;
     19     range.location = loc;
     20     range.length = len;
     21     return range;
     22 }
     23 typedef const void * CFTypeRef;
     24 typedef const struct __CFString * CFStringRef;
     25 typedef const struct __CFAllocator * CFAllocatorRef;
     26 extern const CFAllocatorRef kCFAllocatorDefault;
     27 extern CFTypeRef CFRetain(CFTypeRef cf);
     28 extern void CFRelease(CFTypeRef cf);
     29 typedef struct {
     30 }
     31 CFArrayCallBacks;
     32 extern const CFArrayCallBacks kCFTypeArrayCallBacks;
     33 typedef const struct __CFArray * CFArrayRef;
     34 typedef struct __CFArray * CFMutableArrayRef;
     35 extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
     36 extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
     37 extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
     38 typedef struct {
     39 }
     40 CFDictionaryKeyCallBacks;
     41 extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
     42 typedef struct {
     43 }
     44 CFDictionaryValueCallBacks;
     45 extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
     46 typedef const struct __CFDictionary * CFDictionaryRef;
     47 typedef struct __CFDictionary * CFMutableDictionaryRef;
     48 extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
     49 typedef UInt32 CFStringEncoding;
     50 enum {
     51 kCFStringEncodingMacRoman = 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  };
     52 extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
     53 typedef double CFTimeInterval;
     54 typedef CFTimeInterval CFAbsoluteTime;
     55 extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
     56 typedef const struct __CFDate * CFDateRef;
     57 extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
     58 extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
     59 typedef __darwin_natural_t natural_t;
     60 typedef natural_t mach_port_name_t;
     61 typedef mach_port_name_t mach_port_t;
     62 typedef int kern_return_t;
     63 typedef kern_return_t mach_error_t;
     64 enum {
     65 kCFNumberSInt8Type = 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    };
     66 typedef CFIndex CFNumberType;
     67 typedef const struct __CFNumber * CFNumberRef;
     68 extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
     69 typedef const struct __CFAttributedString *CFAttributedStringRef;
     70 typedef struct __CFAttributedString *CFMutableAttributedStringRef;
     71 extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
     72 extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
     73 extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
     74 typedef signed char BOOL;
     75 typedef unsigned long NSUInteger;
     76 @class NSString, Protocol;
     77 extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
     78 typedef struct _NSZone NSZone;
     79 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
     80 @protocol NSObject
     81 - (BOOL)isEqual:(id)object;
     82 - (id)retain;
     83 - (oneway void)release;
     84 - (id)autorelease;
     85 - (Class)class;
     86 @end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
     87 @end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
     88 @end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
     89 @end
     90 @interface NSObject <NSObject> {}
     91 + (id)allocWithZone:(NSZone *)zone;
     92 + (id)alloc;
     93 - (void)dealloc;
     94 - (oneway void)release;
     95 - (id)copy;
     96 @end
     97 @interface NSObject (NSCoderMethods)
     98 - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
     99 @end
    100 extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
    101 typedef struct {
    102 }
    103 NSFastEnumerationState;
    104 @protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
    105 @end           @class NSString, NSDictionary;
    106 @interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
    107 @end  @interface NSNumber : NSValue  - (char)charValue;
    108 - (id)initWithInt:(int)value;
    109 @end   @class NSString;
    110 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
    111 - (NSUInteger)count;
    112 @end
    113 @interface NSArray (NSArrayCreation)
    114 + (id)array;
    115 + (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
    116 @end
    117        @interface NSAutoreleasePool : NSObject {
    118 }
    119 - (void)drain;
    120 - (id)init;
    121 @end extern NSString * const NSBundleDidLoadNotification;
    122 typedef double NSTimeInterval;
    123 @interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
    124 @end            typedef unsigned short unichar;
    125 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
    126 - ( const char *)UTF8String;
    127 - (id)initWithUTF8String:(const char *)nullTerminatedCString;
    128 + (id)stringWithUTF8String:(const char *)nullTerminatedCString;
    129 @end        @class NSString, NSURL, NSError;
    130 @interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSUInteger)length;
    131 + (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
    132 + (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
    133 @end   @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
    134 @interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
    135 @end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
    136 - (void)setObject:(id)anObject forKey:(id)aKey;
    137 @end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
    138 @end  typedef double CGFloat;
    139 struct CGSize {
    140 };
    141 typedef struct CGSize CGSize;
    142 struct CGRect {
    143 };
    144 typedef struct CGRect CGRect;
    145 typedef mach_port_t io_object_t;
    146 typedef char io_name_t[128];
    147 typedef io_object_t io_iterator_t;
    148 typedef io_object_t io_service_t;
    149 typedef struct IONotificationPort * IONotificationPortRef;
    150 typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
    151 io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
    152 kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
    153 kern_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));
    154 kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
    155 CFMutableDictionaryRef IOServiceMatching(  const char * name );
    156 CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
    157 CFMutableDictionaryRef IOBSDNameMatching(  mach_port_t masterPort,  uint32_t options,  const char * bsdName );
    158 CFMutableDictionaryRef IOOpenFirmwarePathMatching(  mach_port_t masterPort,  uint32_t options,  const char * path );
    159 CFMutableDictionaryRef IORegistryEntryIDMatching(  uint64_t entryID );
    160 typedef struct __DASession * DASessionRef;
    161 extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
    162 typedef struct __DADisk * DADiskRef;
    163 extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
    164 extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
    165 extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
    166 extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
    167 @interface NSTask : NSObject - (id)init;
    168 @end                    typedef struct CGColorSpace *CGColorSpaceRef;
    169 typedef struct CGImage *CGImageRef;
    170 typedef struct CGLayer *CGLayerRef;
    171 @interface NSResponder : NSObject <NSCoding> {
    172 }
    173 @end    @protocol NSAnimatablePropertyContainer      - (id)animator;
    174 @end  extern NSString *NSAnimationTriggerOrderIn ;
    175 @interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
    176 }
    177 @end @protocol NSValidatedUserInterfaceItem - (SEL)action;
    178 @end   @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
    179 @end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
    180 @interface NSApplication : NSResponder <NSUserInterfaceValidations> {
    181 }
    182 @end   enum {
    183 NSTerminateCancel = 0,         NSTerminateNow = 1,         NSTerminateLater = 2 };
    184 typedef NSUInteger NSApplicationTerminateReply;
    185 @protocol NSApplicationDelegate <NSObject> @optional        - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
    186 @end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
    187 @interface NSCell : NSObject <NSCopying, NSCoding> {
    188 }
    189 @end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
    190 typedef struct {
    191 }
    192 CVTimeStamp;
    193 @interface CIImage : NSObject <NSCoding, NSCopying> {
    194 }
    195 typedef int CIFormat;
    196 @end  enum {
    197 kDAReturnSuccess = 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 };
    198 typedef mach_error_t DAReturn;
    199 typedef const struct __DADissenter * DADissenterRef;
    200 extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
    201 @interface CIContext: NSObject {
    202 }
    203 - (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
    204 - (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r     format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
    205 - (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
    206 @end extern NSString* const QCRendererEventKey;
    207 @protocol QCCompositionRenderer - (NSDictionary*) attributes;
    208 @end   @interface QCRenderer : NSObject <QCCompositionRenderer> {
    209 }
    210 - (id) createSnapshotImageOfType:(NSString*)type;
    211 @end  extern NSString* const QCViewDidStartRenderingNotification;
    212 @interface QCView : NSView <QCCompositionRenderer> {
    213 }
    214 - (id) createSnapshotImageOfType:(NSString*)type;
    215 @end    enum {
    216 ICEXIFOrientation1 = 1,     ICEXIFOrientation2 = 2,     ICEXIFOrientation3 = 3,     ICEXIFOrientation4 = 4,     ICEXIFOrientation5 = 5,     ICEXIFOrientation6 = 6,     ICEXIFOrientation7 = 7,     ICEXIFOrientation8 = 8, };
    217 @class ICDevice;
    218 @protocol ICDeviceDelegate <NSObject>  @required      - (void)didRemoveDevice:(ICDevice*)device;
    219 @end extern NSString *const ICScannerStatusWarmingUp;
    220 @class ICScannerDevice;
    221 @protocol ICScannerDeviceDelegate <ICDeviceDelegate>  @optional       - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
    222 @end
    223 CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
    224 
    225 static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef 
    226 cf) {
    227     return cf ? (id)CFMakeCollectable(cf) : ((void*)0);
    228 }
    229 
    230 //===----------------------------------------------------------------------===//
    231 // Test cases.
    232 //===----------------------------------------------------------------------===//
    233 
    234 void f1() {
    235   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
    236   id x = [(id) A autorelease];
    237   CFRelease((CFMutableArrayRef) x);
    238 }
    239 
    240 void f2() {
    241   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
    242   id x = [(id) A retain];
    243   [x release];
    244   [x release];
    245 }
    246 
    247 void f3() {
    248   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
    249   CFMakeCollectable(A);
    250   CFRetain(A);
    251 }
    252 
    253 void f3b() {
    254   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
    255   CFMakeCollectable(A);
    256 }
    257 
    258 
    259 void f4() {
    260   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
    261   NSMakeCollectable(A);
    262   CFRetain(A);
    263 }
    264 
    265 void f4b() {
    266   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
    267   NSMakeCollectable(A);
    268 }
    269 
    270 void f5() {
    271   id x = [NSMakeCollectable(CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks)) autorelease]; // no-warning
    272 }
    273 
    274 void f5b() {
    275   id x = [(id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks) autorelease]; // expected-warning{{leak}}
    276 }
    277 
    278 // Test return of non-owned objects in contexts where an owned object
    279 // is expected.
    280 @interface TestReturnNotOwnedWhenExpectedOwned
    281 - (NSString*)newString;
    282 - (CFMutableArrayRef)newArray;
    283 @end
    284 
    285 @implementation TestReturnNotOwnedWhenExpectedOwned
    286 - (NSString*)newString {
    287   NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object}}
    288   CFRetain(s);
    289   return s;
    290 }
    291 - (CFMutableArrayRef)newArray{
    292    return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
    293 }
    294 @end
    295 
    296 //===----------------------------------------------------------------------===//
    297 // <rdar://problem/6948053> False positive: object substitution during -init*
    298 //   methods warns about returning +0 when using -fobjc-gc-only
    299 //===----------------------------------------------------------------------===//
    300 
    301 @interface MyClassRdar6948053 : NSObject
    302 - (id) init;
    303 + (id) shared;
    304 @end
    305 
    306 @implementation MyClassRdar6948053
    307 +(id) shared {
    308   return (id) 0;
    309 }
    310 - (id) init
    311 {
    312   Class myClass = [self class];  
    313   [self release];
    314   return [[myClass shared] retain]; // no-warning
    315 }
    316 @end
    317 
    318 //===----------------------------------------------------------------------===//
    319 // <rdar://problem/7174400> 'ciContext createCGImage:outputImage fromRect:' returns a retained CF object (not GC'ed)//===----------------------------------------------------------------------===//
    320 //===----------------------------------------------------------------------===//
    321 
    322 void rdar_7174400(QCView *view, QCRenderer *renderer, CIContext *context,
    323                   NSString *str, CIImage *img, CGRect rect,
    324                   CIFormat form, CGColorSpaceRef cs) {
    325   [view createSnapshotImageOfType:str]; // no-warning
    326   [renderer createSnapshotImageOfType:str]; // no-warning
    327   [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
    328   [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
    329 }
    330 
    331 //===----------------------------------------------------------------------===//
    332 // <rdar://problem/6250216> Warn against using -[NSAutoreleasePool release] in 
    333 //  GC mode
    334 //===----------------------------------------------------------------------===//
    335 
    336 void rdar_6250216(void) {
    337     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    338     [pool release]; // expected-warning{{Use -drain instead of -release when using NSAutoreleasePool and garbage collection}}
    339 }
    340 
    341 
    342 //===----------------------------------------------------------------------===//
    343 // <rdar://problem/7407273> Don't crash when analyzing messages sent to blocks
    344 //===----------------------------------------------------------------------===//
    345 
    346 @class RDar7407273;
    347 typedef void (^RDar7407273Block)(RDar7407273 *operation);
    348 void rdar7407273(RDar7407273Block b) {
    349   [b copy];
    350 }
    351 
    352 //===----------------------------------------------------------------------===//
    353 // Tests of ownership attributes.
    354 //===----------------------------------------------------------------------===//
    355 
    356 @interface TestOwnershipAttr : NSObject
    357 - (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained));
    358 - (NSString*) returnsAnOwnedCFString  __attribute__((cf_returns_retained));
    359 @end
    360 
    361 void test_attr_1(TestOwnershipAttr *X) {
    362   NSString *str = [X returnsAnOwnedString]; // no-warning
    363 }
    364 
    365 void test_attr_1b(TestOwnershipAttr *X) {
    366   NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
    367 }
    368 
    369 @interface MyClassTestCFAttr : NSObject {}
    370 - (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
    371 - (NSDate*) alsoReturnsRetained;
    372 - (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
    373 @end
    374 
    375 __attribute__((cf_returns_retained))
    376 CFDateRef returnsRetainedCFDate()  {
    377   return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
    378 }
    379 
    380 @implementation MyClassTestCFAttr
    381 - (NSDate*) returnsCFRetained {
    382   return (NSDate*) returnsRetainedCFDate(); // No leak.
    383 }
    384 
    385 - (NSDate*) alsoReturnsRetained {
    386   return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
    387 }
    388 
    389 - (NSDate*) returnsNSRetained {
    390   return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
    391 }
    392 @end
    393 
    394 
    395 #if __has_feature(attribute_ns_consumed)
    396 #define NS_CONSUMED __attribute__((ns_consumed))
    397 #endif
    398 #if __has_feature(attribute_cf_consumed)
    399 #define CF_CONSUMED __attribute__((cf_consumed))
    400 #endif
    401 
    402 void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void));
    403 void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void));
    404 
    405 void testConsumeAndStopTracking() {
    406   id retained = [@[] retain]; // +0, GC
    407   consumeAndStopTracking(retained, ^{}); // no-warning
    408 
    409   id doubleRetained = [[@[] retain] retain]; // +0, GC
    410   consumeAndStopTracking(doubleRetained, ^{
    411     [doubleRetained release];
    412   }); // no-warning
    413 
    414   id unretained = @[]; // +0
    415   consumeAndStopTracking(unretained, ^{}); // no-warning, GC
    416 }
    417 
    418 void testCFConsumeAndStopTrackingMsg() {
    419   id retained = [@[] retain]; // +0, GC
    420   CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
    421 }
    422 
    423 void testCFConsumeAndStopTracking() {
    424   CFTypeRef retained = returnsRetainedCFDate(); // +1
    425   CFConsumeAndStopTracking(retained, ^{}); // no-warning
    426 
    427   CFTypeRef doubleRetained = CFRetain(returnsRetainedCFDate()); // +2
    428   CFConsumeAndStopTracking(doubleRetained, ^{
    429     CFRelease(doubleRetained);
    430   }); // no-warning
    431 
    432   id unretained = @[]; // +0
    433   CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
    434 }
    435