// 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 {} @end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); typedef double NSTimeInterval; @interface NSDate : NSObject - (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; }