CFDateGC.m revision 1261938ec42b0a1b82bec5fe901b7fc02a23d9a1
1// RUN: clang -checker-cfref -verify -fobjc-gc %s 2 3//===----------------------------------------------------------------------===// 4// The following code is reduced using delta-debugging from 5// Foundation.h and CoreFoundation.h (Mac OS X). 6// 7// It includes the basic definitions for the test cases below. 8// Not directly including [Core]Foundation.h directly makes this test case 9// both svelte and portable to non-Mac platforms. 10//===----------------------------------------------------------------------===// 11 12typedef const void * CFTypeRef; 13void CFRelease(CFTypeRef cf); 14CFTypeRef CFRetain(CFTypeRef cf); 15CFTypeRef CFMakeCollectable(CFTypeRef cf); 16typedef const struct __CFAllocator * CFAllocatorRef; 17typedef double CFTimeInterval; 18typedef CFTimeInterval CFAbsoluteTime; 19typedef const struct __CFDate * CFDateRef; 20extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 21extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); 22typedef struct objc_object {} *id; 23typedef signed char BOOL; 24static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) {} 25@protocol NSObject - (BOOL)isEqual:(id)object; 26- (oneway void)release; 27@end 28@class NSArray; 29 30//===----------------------------------------------------------------------===// 31// Test cases. 32//===----------------------------------------------------------------------===// 33 34CFAbsoluteTime f1_use_after_release() { 35 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 36 CFDateRef date = CFDateCreate(0, t); 37 CFRetain(date); 38 [NSMakeCollectable(date) release]; 39 CFDateGetAbsoluteTime(date); // no-warning 40 CFRelease(date); 41 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} 42 return t; 43} 44 45// The following two test cases verifies that CFMakeCollectable is a no-op 46// in non-GC mode and a "release" in GC mode. 47CFAbsoluteTime f2_leak() { 48 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 49 CFDateRef date = CFDateCreate(0, t); 50 CFRetain(date); 51 [(id) CFMakeCollectable(date) release]; 52 CFDateGetAbsoluteTime(date); // no-warning 53 CFRelease(date); 54 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} 55 return t; 56} 57 58CFAbsoluteTime f2_noleak() { 59 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 60 CFDateRef date = CFDateCreate(0, t); 61 CFRetain(date); 62 [(id) CFMakeCollectable(date) release]; 63 CFDateGetAbsoluteTime(date); // no-warning 64 t = CFDateGetAbsoluteTime(date); // no-warning 65 CFRelease(date); // no-warning 66 return t; 67} 68 69// The following test case verifies that we "stop tracking" a retained object 70// when it is passed as an argument to an implicitly defined function. 71CFAbsoluteTime f4() { 72 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 73 CFDateRef date = CFDateCreate(0, t); 74 CFRetain(date); 75 some_implicitly_defined_function_stop_tracking(date); // no-warning 76 return t; 77} 78