brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.8 KiB · 8b4de9a Raw
354 lines · plain
1// RUN: %clang_analyze_cc1 -std=c++14 \2// RUN:     -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete \3// RUN:     -analyzer-checker=unix.MismatchedDeallocator \4// RUN:     -verify -fblocks %s5 6#import "Inputs/system-header-simulator-objc.h"7#import "Inputs/system-header-simulator-for-malloc.h"8 9// Done with headers. Start testing.10void testNSDatafFreeWhenDoneNoError(NSUInteger dataLength) {11  unsigned char *data = (unsigned char *)malloc(42);12  NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength];13}14 15void testNSDataFreeWhenDoneYES(NSUInteger dataLength) {16  unsigned char *data = (unsigned char *)malloc(42);17  NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning18}19 20void testNSDataFreeWhenDoneYES2(NSUInteger dataLength) {21  unsigned char *data = (unsigned char *)malloc(42);22  NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning23}24 25void testNSDataFreeWhenDoneYES2_with_wrapper(NSUInteger dataLength) {26  unsigned char *data = (unsigned char *)malloc(42);27  Wrapper *nsdata = [[Wrapper alloc] initWithBytesNoCopy:data length:dataLength]; // no-warning28}29 30void testNSStringFreeWhenDoneYES3(NSUInteger dataLength) {31  unsigned char *data = (unsigned char *)malloc(42);32  NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1];33}34 35void testNSStringFreeWhenDoneYES4(NSUInteger dataLength) {36  unichar *data = (unichar*)malloc(42);37  NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1];38  free(data); //expected-warning {{Attempt to release non-owned memory}}39}40 41void testNSStringFreeWhenDoneYES(NSUInteger dataLength) {42  unsigned char *data = (unsigned char *)malloc(42);43  NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; // no-warning44}45 46void testNSStringFreeWhenDoneYES2(NSUInteger dataLength) {47  unichar *data = (unichar*)malloc(42);48  NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; // no-warning49}50 51 52void testNSDataFreeWhenDoneNO(NSUInteger dataLength) {53  unsigned char *data = (unsigned char *)malloc(42);54  NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}55}56 57void testNSDataFreeWhenDoneNO2(NSUInteger dataLength) {58  unsigned char *data = (unsigned char *)malloc(42);59  NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}60}61 62 63void testNSStringFreeWhenDoneNO(NSUInteger dataLength) {64  unsigned char *data = (unsigned char *)malloc(42);65  NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:0]; // expected-warning{{leak}}66}67 68void testNSStringFreeWhenDoneNewDelete(NSUInteger dataLength) {69  unsigned char *data = new unsigned char(42);70  NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data71                                   length:dataLength freeWhenDone:1];72  // expected-warning@-2{{-initWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}73}74 75void testNSStringFreeWhenDoneNewDelete2(NSUInteger dataLength) {76  unsigned char *data = new unsigned char(42);77  NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data78                                                length:dataLength79                                           deallocator:^(void *bytes,80                                                         NSUInteger length) {81                                             delete (unsigned char *)bytes;82                                           }]; // no-warning83}84 85void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) {86  unichar *data = (unichar*)malloc(42);87  NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}88}89 90void testOffsetFree() {91  int *p = (int *)malloc(sizeof(int));92  NSData *nsdata = [NSData dataWithBytesNoCopy:++p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Argument to +dataWithBytesNoCopy:length:freeWhenDone: is offset by 4 bytes from the start of memory allocated by 'malloc()'}}93}94 95void testRelinquished1() {96  void *data = malloc(42);97  NSData *nsdata = [NSData dataWithBytesNoCopy:data length:42 freeWhenDone:1];98  free(data); // expected-warning {{Attempt to release non-owned memory}}99}100 101void testRelinquished2() {102  void *data = malloc(42);103  NSData *nsdata;104  free(data);105  [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is released}}106}107 108@interface My109+ (void)param:(void *)p;110@end111 112void testUseAfterFree() {113  int *p = (int *)malloc(sizeof(int));114  free(p);115  [My param:p];  // expected-warning{{Use of memory after it is released}}116}117 118void testNoCopy() {119  char *p = (char *)calloc(1, sizeof(int));120  CustomData *w = [CustomData somethingNoCopy:p]; // no-warning121}122 123void testFreeWhenDone() {124  char *p = (char *)calloc(1, sizeof(int));125  CustomData *w = [CustomData something:p freeWhenDone:1]; // no-warning126}127 128void testFreeWhenDonePositive() {129  char *p = (char *)calloc(1, sizeof(int));130  CustomData *w = [CustomData something:p freeWhenDone:0]; // expected-warning{{leak}}131}132 133void testFreeWhenDoneNoCopy() {134  int *p = (int *)malloc(sizeof(int));135  CustomData *w = [CustomData somethingNoCopy:p length:sizeof(int) freeWhenDone:1]; // no-warning136}137 138void testFreeWhenDoneNoCopyPositive() {139  int *p = (int *)malloc(sizeof(int));140  CustomData *w = [CustomData somethingNoCopy:p length:sizeof(int) freeWhenDone:0]; // expected-warning{{leak}}141}142 143// Test CF/NS...NoCopy. PR12100: Pointers can escape when custom deallocators are provided.144void testNSDatafFreeWhenDone(NSUInteger dataLength) {145  CFStringRef str;146  char *bytes = (char*)malloc(12);147  str = CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0); // no warning148  CFRelease(str); // default allocator also frees bytes149}150 151void stringWithExternalContentsExample(void) {152#define BufferSize 1000153    CFMutableStringRef mutStr;154    UniChar *myBuffer;155 156    myBuffer = (UniChar *)malloc(BufferSize * sizeof(UniChar));157 158    mutStr = CFStringCreateMutableWithExternalCharactersNoCopy(0, myBuffer, 0, BufferSize, kCFAllocatorNull); // expected-warning{{leak}}159 160    CFRelease(mutStr);161    //free(myBuffer);162}163 164// PR12101 : pointers can escape through custom deallocators set on creation of a container.165void TestCallbackReleasesMemory(CFDictionaryKeyCallBacks keyCallbacks) {166  void *key = malloc(12);167  void *val = malloc(12);168  CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallbacks, &kCFTypeDictionaryValueCallBacks);169  CFDictionarySetValue(x, key, val); 170  return;// no-warning171}172 173NSData *radar10976702() {174  void *bytes = malloc(10);175  return [NSData dataWithBytesNoCopy:bytes length:10]; // no-warning176}177 178void testBlocks() {179  int *x= (int*)malloc(sizeof(int));180  int (^myBlock)(int) = ^(int num) {181    free(x);182    return num;183  };184  myBlock(3);185}186 187// Test NSMapInsert. 188@interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration>189@end190extern void *NSMapGet(NSMapTable *table, const void *key);191extern void NSMapInsert(NSMapTable *table, const void *key, const void *value);192extern void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value);193char *strdup(const char *s);194 195NSString * radar11152419(NSString *string1, NSMapTable *map) {196    const char *strkey = "key";197    NSString *string = ( NSString *)NSMapGet(map, strkey);198    if (!string) {199        string = [string1 copy];200        NSMapInsert(map, strdup(strkey), (void*)string); // no warning201        NSMapInsertKnownAbsent(map, strdup(strkey), (void*)string); // no warning202    }203    return string;204}205 206// Test that we handle pointer escaping through OSAtomicEnqueue.207typedef volatile struct {208 void *opaque1;209 long opaque2;210} OSQueueHead;211extern "C" void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import));212static inline void radar11111210(OSQueueHead *pool) {213    void *newItem = malloc(4);214    OSAtomicEnqueue(pool, newItem, 4);215}216 217// Pointer might escape through CGDataProviderCreateWithData218typedef struct CGDataProvider *CGDataProviderRef;219typedef void (*CGDataProviderReleaseDataCallback)(void *info, const void *data,220    size_t size);221extern CGDataProviderRef CGDataProviderCreateWithData(void *info,222    const void *data, size_t size,223    CGDataProviderReleaseDataCallback releaseData)224    __attribute__((visibility("default")));225void *calloc(size_t, size_t);226 227static void releaseDataCallback (void *info, const void *data, size_t size) {228#pragma unused (info, size)229  free((void*)data);230}231void testCGDataProviderCreateWithData() { 232  void* b = calloc(8, 8);233  CGDataProviderRef p = CGDataProviderCreateWithData(0, b, 8*8, releaseDataCallback);234}235 236// Assume that functions which take a function pointer can free memory even if237// they are defined in system headers and take the const pointer to the238// allocated memory.239extern CGDataProviderRef UnknownFunWithCallback(void *info,240    const void *data, size_t size,241    CGDataProviderReleaseDataCallback releaseData)242    __attribute__((visibility("default")));243void testUnknownFunWithCallBack() { 244  void* b = calloc(8, 8);245  CGDataProviderRef p = UnknownFunWithCallback(0, b, 8*8, releaseDataCallback);246}247 248// Test blocks.249void acceptBlockParam(void *, void (^block)(void *), unsigned);250void testCallWithBlockCallback() {251  void *l = malloc(12);252  acceptBlockParam(l, ^(void *i) { free(i); }, sizeof(char *));253}254 255// Test blocks in system headers.256void testCallWithBlockCallbackInSystem() {257  void *l = malloc(12);258  SystemHeaderFunctionWithBlockParam(l, ^(void *i) { free(i); }, sizeof(char *));259}260 261// Test escape into NSPointerArray. PR13140262void foo(NSPointerArray* pointerArray) {263  264  void* p1 = malloc (1024);265  if (p1) {266    [pointerArray addPointer:p1];267  }268 269  void* p2 = malloc (1024);270  if (p2) {271    [pointerArray insertPointer:p2 atIndex:1];272  }273 274  void* p3 = malloc (1024);275  if (p3) {276    [pointerArray replacePointerAtIndex:1 withPointer:p3];277  }278 279  // Freeing the buffer is allowed.280  void* buffer = [pointerArray pointerAtIndex:0];281  free(buffer);282}283 284void noCrashOnVariableArgumentSelector() {285  NSMutableString *myString = [NSMutableString stringWithString:@"some text"];286  [myString appendFormat:@"some text = %d", 3];287}288 289void test12365078_check() {290  unichar *characters = (unichar*)malloc(12);291  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];292  if (!string) free(characters); // no-warning293}294 295void test12365078_nocheck() {296  unichar *characters = (unichar*)malloc(12);297  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];298}299 300void test12365078_false_negative() {301  unichar *characters = (unichar*)malloc(12);302  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];303  if (!string) {;}304}305 306void test12365078_no_malloc(unichar *characters) {307  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];308  if (!string) {free(characters);}309}310 311NSString *test12365078_no_malloc_returnValue(unichar *characters) {312  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];313  if (!string) {314    return 0; // no-warning315  }316  return string;317}318 319void test12365078_nocheck_nomalloc(unichar *characters) {320  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];321  free(characters); // expected-warning {{Attempt to release non-owned memory}}322}323 324void test12365078_nested(unichar *characters) {325  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];326  if (!string) {    327    NSString *string2 = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];328    if (!string2) {    329      NSString *string3 = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];330      if (!string3) {    331        NSString *string4 = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];332        if (!string4)333          free(characters);334      }335    }336  }337}338 339void test12365078_check_positive() {340  unichar *characters = (unichar*)malloc(12);341  NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1];342  if (string) free(characters); // expected-warning{{Attempt to release non-owned memory}}343}344 345void *test_reinterpret_cast_to_block() {346  // Used to leak because the pointer was disappearing347  // during the reinterpret_cast.348  using BlockPtrTy = void (^)();349  struct Block {};350  Block* block = static_cast<Block*>(malloc(sizeof(Block)));351  BlockPtrTy blockPtr = reinterpret_cast<BlockPtrTy>(block); // no-warning352  return blockPtr;353}354