144 lines
4.2 KiB
Objective-C
144 lines
4.2 KiB
Objective-C
// 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;
|
|
}
|