| // 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; |
| } |