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