[analyzer] More tests for "release and stop tracking".

Under GC, a release message is ignored, so "release and stop tracking" just
becomes "stop tracking". But CFRelease is still honored. This is the main
difference between ns_consumed and cf_consumed.

llvm-svn: 162234
This commit is contained in:
Jordan Rose 2012-08-20 22:15:44 +00:00
parent 6bae2a57d5
commit eaacff4826
2 changed files with 67 additions and 4 deletions

View File

@ -107,9 +107,14 @@ NSFastEnumerationState;
@end @interface NSNumber : NSValue - (char)charValue;
- (id)initWithInt:(int)value;
@end @class NSString;
@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
@end @interface NSArray (NSArrayCreation) + (id)array;
@end @interface NSAutoreleasePool : NSObject {
@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
- (NSUInteger)count;
@end
@interface NSArray (NSArrayCreation)
+ (id)array;
+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
@end
@interface NSAutoreleasePool : NSObject {
}
- (void)drain;
- (id)init;
@ -385,3 +390,45 @@ CFDateRef returnsRetainedCFDate() {
return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
}
@end
#if __has_feature(attribute_ns_consumed)
#define NS_CONSUMED __attribute__((ns_consumed))
#endif
#if __has_feature(attribute_cf_consumed)
#define CF_CONSUMED __attribute__((cf_consumed))
#endif
void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void));
void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void));
void testConsumeAndStopTracking() {
id retained = [@[] retain]; // +0, GC
consumeAndStopTracking(retained, ^{}); // no-warning
id doubleRetained = [[@[] retain] retain]; // +0, GC
consumeAndStopTracking(doubleRetained, ^{
[doubleRetained release];
}); // no-warning
id unretained = @[]; // +0
consumeAndStopTracking(unretained, ^{}); // no-warning, GC
}
void testCFConsumeAndStopTrackingMsg() {
id retained = [@[] retain]; // +0, GC
CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}
void testCFConsumeAndStopTracking() {
CFTypeRef retained = returnsRetainedCFDate(); // +1
CFConsumeAndStopTracking(retained, ^{}); // no-warning
CFTypeRef doubleRetained = CFRetain(returnsRetainedCFDate()); // +2
CFConsumeAndStopTracking(doubleRetained, ^{
CFRelease(doubleRetained);
}); // no-warning
id unretained = @[]; // +0
CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}

View File

@ -1748,7 +1748,7 @@ extern id NSApp;
@end
//===----------------------------------------------------------------------===//
// Test returning allocated memory in a struct.
//
//
// We currently don't have a general way to track pointers that "escape".
// Here we test that RetainCountChecker doesn't get excited about returning
// allocated CF objects in struct fields.
@ -1856,7 +1856,10 @@ id makeCollectableNonLeak() {
return [objCObject autorelease]; // +0
}
void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void));
void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void));
void testConsumeAndStopTracking() {
id retained = [@[] retain]; // +1
consumeAndStopTracking(retained, ^{}); // no-warning
@ -1869,3 +1872,16 @@ void testConsumeAndStopTracking() {
id unretained = @[]; // +0
consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}
void testCFConsumeAndStopTracking() {
id retained = [@[] retain]; // +1
CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning
id doubleRetained = [[@[] retain] retain]; // +2
CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{
[doubleRetained release];
}); // no-warning
id unretained = @[]; // +0
CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}