diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/Analysis/malloc.mm | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/Analysis/malloc.mm')
-rw-r--r-- | clang/test/Analysis/malloc.mm | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/clang/test/Analysis/malloc.mm b/clang/test/Analysis/malloc.mm new file mode 100644 index 0000000..3515a4f --- /dev/null +++ b/clang/test/Analysis/malloc.mm @@ -0,0 +1,156 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s +#include "system-header-simulator-objc.h" + +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 +} + +void testNSDataFreeWhenDoneYES(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning +} + +void testNSDataFreeWhenDoneYES2(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning +} + + +void testNSStringFreeWhenDoneYES(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; // no-warning +} + +void testNSStringFreeWhenDoneYES2(NSUInteger dataLength) { + unichar *data = (unichar*)malloc(42); + NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; // no-warning +} + + +void testNSDataFreeWhenDoneNO(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} +} + +void testNSDataFreeWhenDoneNO2(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} +} + + +void testNSStringFreeWhenDoneNO(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:0]; // expected-warning{{leak}} +} + +void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) { + unichar *data = (unichar*)malloc(42); + NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} +} + +// TODO: False Negative. +void testNSDatafFreeWhenDoneFN(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1]; + free(data); // false negative +} + +// Test CF/NS...NoCopy. PR12100: Pointers can escape when custom deallocators are provided. +void testNSDatafFreeWhenDone(NSUInteger dataLength) { + CFStringRef str; + char *bytes = (char*)malloc(12); + str = CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0); // no warning + CFRelease(str); // default allocator also frees bytes +} + +void stringWithExternalContentsExample(void) { +#define BufferSize 1000 + CFMutableStringRef mutStr; + UniChar *myBuffer; + + myBuffer = (UniChar *)malloc(BufferSize * sizeof(UniChar)); + + mutStr = CFStringCreateMutableWithExternalCharactersNoCopy(0, myBuffer, 0, BufferSize, kCFAllocatorNull); // expected-warning{{leak}} + + CFRelease(mutStr); + //free(myBuffer); +} + +// PR12101 : pointers can escape through custom deallocators set on creation of a container. +void TestCallbackReleasesMemory(CFDictionaryKeyCallBacks keyCallbacks) { + void *key = malloc(12); + void *val = malloc(12); + CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallbacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(x, key, val); + return;// no-warning +} + +NSData *radar10976702() { + void *bytes = malloc(10); + return [NSData dataWithBytesNoCopy:bytes length:10]; // no-warning +} + +void testBlocks() { + int *x= (int*)malloc(sizeof(int)); + int (^myBlock)(int) = ^(int num) { + free(x); + return num; + }; + myBlock(3); +} + +// Test NSMapInsert. +@interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration> +@end +extern void *NSMapGet(NSMapTable *table, const void *key); +extern void NSMapInsert(NSMapTable *table, const void *key, const void *value); +extern void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value); +char *strdup(const char *s); + +NSString * radar11152419(NSString *string1, NSMapTable *map) { + const char *strkey = "key"; + NSString *string = ( NSString *)NSMapGet(map, strkey); + if (!string) { + string = [string1 copy]; + NSMapInsert(map, strdup(strkey), (void*)string); // no warning + NSMapInsertKnownAbsent(map, strdup(strkey), (void*)string); // no warning + } + return string; +} + +// Test that we handle pointer escaping through OSAtomicEnqueue. +typedef volatile struct { + void *opaque1; + long opaque2; +} OSQueueHead; +void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import)); +static inline void radar11111210(OSQueueHead *pool) { + void *newItem = malloc(4); + OSAtomicEnqueue(pool, newItem, 4); +} + +// Pointer might escape through CGDataProviderCreateWithData (radar://11187558). +typedef struct CGDataProvider *CGDataProviderRef; +typedef void (*CGDataProviderReleaseDataCallback)(void *info, const void *data, + size_t size); +extern CGDataProviderRef CGDataProviderCreateWithData(void *info, + const void *data, size_t size, + CGDataProviderReleaseDataCallback releaseData) + __attribute__((visibility("default"))); +void *calloc(size_t, size_t); + +static void releaseDataCallback (void *info, const void *data, size_t size) { +#pragma unused (info, size) + free((void*)data); +} +void testCGDataProviderCreateWithData() { + void* b = calloc(8, 8); + CGDataProviderRef p = CGDataProviderCreateWithData(0, b, 8*8, releaseDataCallback); +}
\ No newline at end of file |