diff options
-rw-r--r-- | test/Analysis/malloc.c | 15 | ||||
-rw-r--r-- | test/Analysis/malloc.mm | 76 |
2 files changed, 91 insertions, 0 deletions
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 58dbfdef12..f475fee1b4 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -485,6 +485,13 @@ void GlobalStructMallocFree() { free(GlS.x); } +char *ArrayG[12]; + +void globalArrayTest() { + char *p = (char*)malloc(12); + ArrayG[0] = p; +} + // Make sure that we properly handle a pointer stored into a local struct/array. typedef struct _StructWithPtr { int *memP; @@ -635,3 +642,11 @@ void testMalloc5() { StructWithPtr *pSt = &St; pSt->memP = malloc(12); } + +// TODO: This should produce a warning, similar to the previous issue. +void localArrayTest() { + char *p = (char*)malloc(12); + char *ArrayL[12]; + ArrayL[0] = p; +} + diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm new file mode 100644 index 0000000000..3dd6a10f5f --- /dev/null +++ b/test/Analysis/malloc.mm @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.unix.Malloc -analyzer-store=region -verify %s + +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 +} |