2012-02-21 05:10:37 +08:00
|
|
|
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify %s
|
2012-02-17 06:26:15 +08:00
|
|
|
|
|
|
|
typedef unsigned int UInt32;
|
|
|
|
typedef signed long CFIndex;
|
|
|
|
typedef signed char BOOL;
|
|
|
|
typedef unsigned long NSUInteger;
|
|
|
|
@class NSString, Protocol;
|
|
|
|
extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
|
|
|
|
typedef struct _NSZone NSZone;
|
|
|
|
@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
|
|
|
|
@protocol NSObject
|
|
|
|
- (BOOL)isEqual:(id)object;
|
|
|
|
- (id)retain;
|
|
|
|
- (oneway void)release;
|
|
|
|
- (id)autorelease;
|
|
|
|
- (id)init;
|
|
|
|
@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
|
|
|
|
@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
|
|
|
|
@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
|
|
|
|
@end
|
|
|
|
@interface NSObject <NSObject> {}
|
|
|
|
+ (id)allocWithZone:(NSZone *)zone;
|
|
|
|
+ (id)alloc;
|
|
|
|
- (void)dealloc;
|
|
|
|
@end
|
|
|
|
@interface NSObject (NSCoderMethods)
|
|
|
|
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
|
|
|
|
@end
|
|
|
|
extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
|
|
|
|
typedef struct {
|
|
|
|
}
|
|
|
|
NSFastEnumerationState;
|
|
|
|
@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
|
|
|
|
@end @class NSString, NSDictionary;
|
|
|
|
@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value;
|
|
|
|
@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 {
|
|
|
|
}
|
|
|
|
- (void)drain;
|
|
|
|
@end extern NSString * const NSBundleDidLoadNotification;
|
|
|
|
typedef double NSTimeInterval;
|
|
|
|
@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate;
|
|
|
|
@end typedef unsigned short unichar;
|
|
|
|
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
|
|
|
|
- (NSUInteger)length;
|
|
|
|
- (NSString *)stringByAppendingString:(NSString *)aString;
|
|
|
|
- ( const char *)UTF8String;
|
|
|
|
- (id)initWithUTF8String:(const char *)nullTerminatedCString;
|
|
|
|
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
|
|
|
|
@end @class NSString, NSURL, NSError;
|
|
|
|
@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
|
|
|
|
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
|
|
|
|
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
|
|
|
|
@end
|
|
|
|
|
|
|
|
typedef __typeof(sizeof(int)) size_t;
|
|
|
|
void *malloc(size_t);
|
|
|
|
void free(void *);
|
|
|
|
|
|
|
|
// Done with headers. Start testing.
|
|
|
|
void testNSDatafFreeWhenDoneNoError(NSUInteger dataLength) {
|
|
|
|
unsigned char *data = (unsigned char *)malloc(42);
|
|
|
|
NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength];
|
|
|
|
free(data); // no warning
|
|
|
|
}
|
|
|
|
|
|
|
|
// False Negative
|
|
|
|
void testNSDatafFreeWhenDone(NSUInteger dataLength) {
|
|
|
|
unsigned char *data = (unsigned char *)malloc(42);
|
|
|
|
NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1];
|
|
|
|
free(data); // false negative
|
|
|
|
}
|