diff options
Diffstat (limited to 'test/Analysis')
-rw-r--r-- | test/Analysis/CFDate.m | 143 | ||||
-rw-r--r-- | test/Analysis/CFDateGC.m | 41 | ||||
-rw-r--r-- | test/Analysis/CFString.c | 60 | ||||
-rw-r--r-- | test/Analysis/retain-release.m | 239 |
4 files changed, 272 insertions, 211 deletions
diff --git a/test/Analysis/CFDate.m b/test/Analysis/CFDate.m deleted file mode 100644 index ed076c680b..0000000000 --- a/test/Analysis/CFDate.m +++ /dev/null @@ -1,143 +0,0 @@ -// RUN: clang -checker-cfref -verify %s - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from -// Foundation.h (Mac OS X). -// -// It includes the basic definitions for the test cases below. -// Not including Foundation.h directly makes this test case both svelte and -// portable to non-Mac platforms. -//===----------------------------------------------------------------------===// - -typedef const struct __CFAllocator * CFAllocatorRef; -typedef double CFTimeInterval; -typedef CFTimeInterval CFAbsoluteTime; -typedef const struct __CFDate * CFDateRef; -extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); -typedef struct objc_object {} *id; -typedef signed char BOOL; -typedef unsigned int NSUInteger; -typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject - (BOOL)isEqual:(id)object; - (id)retain; - (oneway void)release; @end -@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end -@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end -@interface NSObject <NSObject> {} @end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -typedef double NSTimeInterval; -@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; @end -@class NSString, NSArray, NSTimeZone; - -//===----------------------------------------------------------------------===// -// Test cases. -//===----------------------------------------------------------------------===// - -CFAbsoluteTime f1() { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - CFRetain(date); - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - CFRelease(date); - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} - return t; -} - -CFAbsoluteTime f2() { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} - return t; -} - - -NSDate* global_x; - - // Test to see if we supresss an error when we store the pointer - // to a global. - -CFAbsoluteTime f3() { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - global_x = (NSDate*) date; - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // no-warning - return t; -} - -// Test to see if we supresss an error when we store the pointer -// to a struct. - -struct foo { - NSDate* f; -}; - -CFAbsoluteTime f4() { - struct foo x; - - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - x.f = (NSDate*) date; - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // no-warning - return t; -} - -// Test a leak. - -CFAbsoluteTime f5(int x) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - - if (x) - CFRelease(date); - - return t; // expected-warning{{leak}} -} - -// Test a leak involving the return. - -CFDateRef f6(int x) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); - CFRetain(date); - return date; // expected-warning{{leak}} -} - -// Test a leak involving an overwrite. - -CFDateRef f7() { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); - CFRetain(date); //expected-warning{{leak}} - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); - return date; -} - -// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and -// has the word create. - -CFDateRef MyDateCreate(); - -CFDateRef f8() { - CFDateRef date = MyDateCreate(); - CFRetain(date); - return date; // expected-warning{{leak}} -} - -CFDateRef f9() { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); - int *p = 0; - // test that the checker assumes that CFDateCreate returns a non-null - // pointer - if (!date) *p = 1; // no-warning - return date; -} diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m index 311371399a..04d2209a3c 100644 --- a/test/Analysis/CFDateGC.m +++ b/test/Analysis/CFDateGC.m @@ -10,24 +10,28 @@ //===----------------------------------------------------------------------===// typedef const void * CFTypeRef; +void CFRelease(CFTypeRef cf); +CFTypeRef CFRetain(CFTypeRef cf); +CFTypeRef CFMakeCollectable(CFTypeRef cf); typedef const struct __CFAllocator * CFAllocatorRef; typedef double CFTimeInterval; typedef CFTimeInterval CFAbsoluteTime; typedef const struct __CFDate * CFDateRef; extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); +extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); +typedef struct objc_object {} *id; typedef signed char BOOL; -typedef unsigned int NSUInteger; -typedef struct _NSZone NSZone; static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) {} -@protocol NSObject - (BOOL)isEqual:(id)object; - (oneway void)release; @end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -CFTypeRef CFMakeCollectable(CFTypeRef cf); +@protocol NSObject - (BOOL)isEqual:(id)object; +- (oneway void)release; +@end +@class NSArray; //===----------------------------------------------------------------------===// // Test cases. //===----------------------------------------------------------------------===// -CFAbsoluteTime f1() { +CFAbsoluteTime f1_use_after_release() { CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); CFDateRef date = CFDateCreate(0, t); CFRetain(date); @@ -38,7 +42,20 @@ CFAbsoluteTime f1() { return t; } -CFAbsoluteTime f1b() { +// The following two test cases verifies that CFMakeCollectable is a no-op +// in non-GC mode and a "release" in GC mode. +CFAbsoluteTime f2_leak() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + CFRetain(date); + [(id) CFMakeCollectable(date) release]; + CFDateGetAbsoluteTime(date); // no-warning + CFRelease(date); + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} + return t; +} + +CFAbsoluteTime f2_noleak() { CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); CFDateRef date = CFDateCreate(0, t); CFRetain(date); @@ -49,4 +66,12 @@ CFAbsoluteTime f1b() { return t; } - +// The following test case verifies that we "stop tracking" a retained object +// when it is passed as an argument to an implicitly defined function. +CFAbsoluteTime f4() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + CFRetain(date); + some_implicitly_defined_function_stop_tracking(date); // no-warning + return t; +} diff --git a/test/Analysis/CFString.c b/test/Analysis/CFString.c deleted file mode 100644 index cb53bb1c66..0000000000 --- a/test/Analysis/CFString.c +++ /dev/null @@ -1,60 +0,0 @@ -// RUN: clang -checker-cfref -pedantic -verify %s - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from -// CoreFoundation.h (Mac OS X). -// -// It includes the basic definitions for the test cases below. -// Not directly including CoreFoundation.h directly makes this test case -// both svelte and portable to non-Mac platforms. -//===----------------------------------------------------------------------===// - -typedef unsigned long UInt32; -typedef unsigned char Boolean; -typedef signed long CFIndex; -typedef const void * CFTypeRef; -typedef const struct __CFString * CFStringRef; -typedef struct { CFIndex location; } CFRange; -typedef const struct __CFAllocator * CFAllocatorRef; -extern void CFRelease(CFTypeRef cf); -typedef Boolean (*CFArrayEqualCallBack)(const void *value1, const void *value2); -typedef struct { CFArrayEqualCallBack equal; } CFArrayCallBacks; -extern const CFArrayCallBacks kCFTypeArrayCallBacks; -typedef const struct __CFArray * CFArrayRef; -typedef struct __CFArray * CFMutableArrayRef; -extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); -extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); -extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); -typedef UInt32 CFStringEncoding; -enum { 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 }; -extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); - -//===----------------------------------------------------------------------===// -// Test cases. -//===----------------------------------------------------------------------===// - -void f1() { - - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - - // Create a string. - CFStringRef s1 = CFStringCreateWithCString(0, "hello world", - kCFStringEncodingUTF8); - - // Add the string to the array. - CFArrayAppendValue(A, s1); - - // Decrement the reference count. - CFRelease(s1); // no-warning - - // Get the string. We don't own it. - s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); - - // Release the array. - CFRelease(A); // no-warning - - // Release the string. This is a bug. - CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} -} - diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m new file mode 100644 index 0000000000..b548f2d26b --- /dev/null +++ b/test/Analysis/retain-release.m @@ -0,0 +1,239 @@ +// RUN: clang -checker-cfref -verify %s + +//===----------------------------------------------------------------------===// +// The following code is reduced using delta-debugging from +// Foundation.h (Mac OS X). +// +// It includes the basic definitions for the test cases below. +// Not including Foundation.h directly makes this test case both svelte and +// portable to non-Mac platforms. +//===----------------------------------------------------------------------===// + +typedef unsigned int __darwin_natural_t; +typedef unsigned long UInt32; +typedef signed long CFIndex; +typedef const void * CFTypeRef; +typedef const struct __CFString * CFStringRef; +typedef const struct __CFAllocator * CFAllocatorRef; +extern const CFAllocatorRef kCFAllocatorDefault; +extern CFTypeRef CFRetain(CFTypeRef cf); +extern void CFRelease(CFTypeRef cf); +typedef struct { +} +CFArrayCallBacks; +extern const CFArrayCallBacks kCFTypeArrayCallBacks; +typedef const struct __CFArray * CFArrayRef; +typedef struct __CFArray * CFMutableArrayRef; +extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); +extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); +typedef const struct __CFDictionary * CFDictionaryRef; +typedef UInt32 CFStringEncoding; +enum { +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 }; +extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); +typedef double CFTimeInterval; +typedef CFTimeInterval CFAbsoluteTime; +typedef const struct __CFDate * CFDateRef; +extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); +extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); +typedef __darwin_natural_t natural_t; +typedef natural_t mach_port_name_t; +typedef mach_port_name_t mach_port_t; +typedef signed char BOOL; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject - (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; +@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; +@end @interface NSObject <NSObject> { +} +@end typedef float CGFloat; +typedef double NSTimeInterval; +@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; +@end enum { +NSObjCNoType = 0, NSObjCVoidType = 'v', NSObjCCharType = 'c', NSObjCShortType = 's', NSObjCLongType = 'l', NSObjCLonglongType = 'q', NSObjCFloatType = 'f', NSObjCDoubleType = 'd', NSObjCBoolType = 'B', NSObjCSelectorType = ':', NSObjCObjectType = '@', NSObjCStructType = '{', NSObjCPointerType = '^', NSObjCStringType = '*', NSObjCArrayType = '[', NSObjCUnionType = '(', NSObjCBitfield = 'b' } +__attribute__((deprecated)); +typedef int kern_return_t; +typedef kern_return_t mach_error_t; +typedef mach_port_t io_object_t; +typedef io_object_t io_service_t; +typedef struct __DASession * DASessionRef; +extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); +typedef struct __DADisk * DADiskRef; +extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); +extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); +extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); +extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); +@interface NSAppleEventManager : NSObject { +} +@end enum { +kDAReturnSuccess = 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 }; +typedef mach_error_t DAReturn; +typedef const struct __DADissenter * DADissenterRef; +extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); + +//===----------------------------------------------------------------------===// +// Test cases. +//===----------------------------------------------------------------------===// + +CFAbsoluteTime f1() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + CFRetain(date); + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + CFRelease(date); + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} + return t; +} + +CFAbsoluteTime f2() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} + return t; +} + + +NSDate* global_x; + +// Test to see if we supresss an error when we store the pointer +// to a global. + +CFAbsoluteTime f3() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + global_x = (NSDate*) date; + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // no-warning + return t; +} + +// Test to see if we supresss an error when we store the pointer +// to a struct. + +struct foo { + NSDate* f; +}; + +CFAbsoluteTime f4() { + struct foo x; + + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + x.f = (NSDate*) date; + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // no-warning + return t; +} + +// Test a leak. + +CFAbsoluteTime f5(int x) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + + if (x) + CFRelease(date); + + return t; // expected-warning{{leak}} +} + +// Test a leak involving the return. + +CFDateRef f6(int x) { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + CFRetain(date); + return date; // expected-warning{{leak}} +} + +// Test a leak involving an overwrite. + +CFDateRef f7() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + CFRetain(date); //expected-warning{{leak}} + date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + return date; +} + +// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and +// has the word create. +CFDateRef MyDateCreate(); + +CFDateRef f8() { + CFDateRef date = MyDateCreate(); + CFRetain(date); + return date; // expected-warning{{leak}} +} + +CFDateRef f9() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + int *p = 0; + // test that the checker assumes that CFDateCreate returns a non-null + // pointer + if (!date) *p = 1; // no-warning + return date; +} + +// Handle DiskArbitration API: +// +// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ +// +void f10(io_service_t media, DADiskRef d, CFStringRef s) { + DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); + if (disk) NSLog(@"ok"); // expected-warning{{leak}} + + disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); + if (disk) NSLog(@"ok"); // expected-warning{{leak}} + + CFDictionaryRef dict = DADiskCopyDescription(d); + if (dict) NSLog(@"ok"); // expected-warning{{leak}} + + disk = DADiskCopyWholeDisk(d); + if (disk) NSLog(@"ok"); // expected-warning{{leak}} + + DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, + kDAReturnSuccess, s); + if (dissenter) NSLog(@"ok"); // expected-warning{{leak}} + + DASessionRef session = DASessionCreate(kCFAllocatorDefault); + if (session) NSLog(@"ok"); // expected-warning{{leak}} +} + +// Test retain/release checker with CFString and CFMutableArray. +void f11() { + // Create the array. + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + + // Create a string. + CFStringRef s1 = CFStringCreateWithCString(0, "hello world", + kCFStringEncodingUTF8); + + // Add the string to the array. + CFArrayAppendValue(A, s1); + + // Decrement the reference count. + CFRelease(s1); // no-warning + + // Get the string. We don't own it. + s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); + + // Release the array. + CFRelease(A); // no-warning + + // Release the string. This is a bug. + CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} +} + |