1*f4a2713aSLionel Sambuc// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s 2*f4a2713aSLionel Sambuc#import "Inputs/system-header-simulator-objc.h" 3*f4a2713aSLionel Sambuc#import "Inputs/system-header-simulator-for-malloc.h" 4*f4a2713aSLionel Sambuc 5*f4a2713aSLionel Sambuc// Done with headers. Start testing. 6*f4a2713aSLionel Sambucvoid testNSDatafFreeWhenDoneNoError(NSUInteger dataLength) { 7*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 8*f4a2713aSLionel Sambuc NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength]; 9*f4a2713aSLionel Sambuc} 10*f4a2713aSLionel Sambuc 11*f4a2713aSLionel Sambucvoid testNSDataFreeWhenDoneYES(NSUInteger dataLength) { 12*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 13*f4a2713aSLionel Sambuc NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning 14*f4a2713aSLionel Sambuc} 15*f4a2713aSLionel Sambuc 16*f4a2713aSLionel Sambucvoid testNSDataFreeWhenDoneYES2(NSUInteger dataLength) { 17*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 18*f4a2713aSLionel Sambuc NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning 19*f4a2713aSLionel Sambuc} 20*f4a2713aSLionel Sambuc 21*f4a2713aSLionel Sambucvoid testNSDataFreeWhenDoneYES2_with_wrapper(NSUInteger dataLength) { 22*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 23*f4a2713aSLionel Sambuc Wrapper *nsdata = [[Wrapper alloc] initWithBytesNoCopy:data length:dataLength]; // no-warning 24*f4a2713aSLionel Sambuc} 25*f4a2713aSLionel Sambuc 26*f4a2713aSLionel Sambucvoid testNSStringFreeWhenDoneYES3(NSUInteger dataLength) { 27*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 28*f4a2713aSLionel Sambuc NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; 29*f4a2713aSLionel Sambuc} 30*f4a2713aSLionel Sambuc 31*f4a2713aSLionel Sambucvoid testNSStringFreeWhenDoneYES4(NSUInteger dataLength) { 32*f4a2713aSLionel Sambuc unichar *data = (unichar*)malloc(42); 33*f4a2713aSLionel Sambuc NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; 34*f4a2713aSLionel Sambuc free(data); //expected-warning {{Attempt to free non-owned memory}} 35*f4a2713aSLionel Sambuc} 36*f4a2713aSLionel Sambuc 37*f4a2713aSLionel Sambucvoid testNSStringFreeWhenDoneYES(NSUInteger dataLength) { 38*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 39*f4a2713aSLionel Sambuc NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; // no-warning 40*f4a2713aSLionel Sambuc} 41*f4a2713aSLionel Sambuc 42*f4a2713aSLionel Sambucvoid testNSStringFreeWhenDoneYES2(NSUInteger dataLength) { 43*f4a2713aSLionel Sambuc unichar *data = (unichar*)malloc(42); 44*f4a2713aSLionel Sambuc NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; // no-warning 45*f4a2713aSLionel Sambuc} 46*f4a2713aSLionel Sambuc 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambucvoid testNSDataFreeWhenDoneNO(NSUInteger dataLength) { 49*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 50*f4a2713aSLionel Sambuc NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} 51*f4a2713aSLionel Sambuc} 52*f4a2713aSLionel Sambuc 53*f4a2713aSLionel Sambucvoid testNSDataFreeWhenDoneNO2(NSUInteger dataLength) { 54*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 55*f4a2713aSLionel Sambuc NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} 56*f4a2713aSLionel Sambuc} 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambucvoid testNSStringFreeWhenDoneNO(NSUInteger dataLength) { 60*f4a2713aSLionel Sambuc unsigned char *data = (unsigned char *)malloc(42); 61*f4a2713aSLionel Sambuc NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:0]; // expected-warning{{leak}} 62*f4a2713aSLionel Sambuc} 63*f4a2713aSLionel Sambuc 64*f4a2713aSLionel Sambucvoid testNSStringFreeWhenDoneNO2(NSUInteger dataLength) { 65*f4a2713aSLionel Sambuc unichar *data = (unichar*)malloc(42); 66*f4a2713aSLionel Sambuc NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} 67*f4a2713aSLionel Sambuc} 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel Sambucvoid testOffsetFree() { 70*f4a2713aSLionel Sambuc int *p = (int *)malloc(sizeof(int)); 71*f4a2713aSLionel Sambuc 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()}} 72*f4a2713aSLionel Sambuc} 73*f4a2713aSLionel Sambuc 74*f4a2713aSLionel Sambucvoid testRelinquished1() { 75*f4a2713aSLionel Sambuc void *data = malloc(42); 76*f4a2713aSLionel Sambuc NSData *nsdata = [NSData dataWithBytesNoCopy:data length:42 freeWhenDone:1]; 77*f4a2713aSLionel Sambuc free(data); // expected-warning {{Attempt to free non-owned memory}} 78*f4a2713aSLionel Sambuc} 79*f4a2713aSLionel Sambuc 80*f4a2713aSLionel Sambucvoid testRelinquished2() { 81*f4a2713aSLionel Sambuc void *data = malloc(42); 82*f4a2713aSLionel Sambuc NSData *nsdata; 83*f4a2713aSLionel Sambuc free(data); 84*f4a2713aSLionel Sambuc [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is freed}} 85*f4a2713aSLionel Sambuc} 86*f4a2713aSLionel Sambuc 87*f4a2713aSLionel Sambuc@interface My 88*f4a2713aSLionel Sambuc+ (void)param:(void *)p; 89*f4a2713aSLionel Sambuc@end 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambucvoid testUseAfterFree() { 92*f4a2713aSLionel Sambuc int *p = (int *)malloc(sizeof(int)); 93*f4a2713aSLionel Sambuc free(p); 94*f4a2713aSLionel Sambuc [My param:p]; // expected-warning{{Use of memory after it is freed}} 95*f4a2713aSLionel Sambuc} 96*f4a2713aSLionel Sambuc 97*f4a2713aSLionel Sambucvoid testNoCopy() { 98*f4a2713aSLionel Sambuc char *p = (char *)calloc(sizeof(int), 1); 99*f4a2713aSLionel Sambuc CustomData *w = [CustomData somethingNoCopy:p]; // no-warning 100*f4a2713aSLionel Sambuc} 101*f4a2713aSLionel Sambuc 102*f4a2713aSLionel Sambucvoid testFreeWhenDone() { 103*f4a2713aSLionel Sambuc char *p = (char *)calloc(sizeof(int), 1); 104*f4a2713aSLionel Sambuc CustomData *w = [CustomData something:p freeWhenDone:1]; // no-warning 105*f4a2713aSLionel Sambuc} 106*f4a2713aSLionel Sambuc 107*f4a2713aSLionel Sambucvoid testFreeWhenDonePositive() { 108*f4a2713aSLionel Sambuc char *p = (char *)calloc(sizeof(int), 1); 109*f4a2713aSLionel Sambuc CustomData *w = [CustomData something:p freeWhenDone:0]; // expected-warning{{leak}} 110*f4a2713aSLionel Sambuc} 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambucvoid testFreeWhenDoneNoCopy() { 113*f4a2713aSLionel Sambuc int *p = (int *)malloc(sizeof(int)); 114*f4a2713aSLionel Sambuc CustomData *w = [CustomData somethingNoCopy:p length:sizeof(int) freeWhenDone:1]; // no-warning 115*f4a2713aSLionel Sambuc} 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambucvoid testFreeWhenDoneNoCopyPositive() { 118*f4a2713aSLionel Sambuc int *p = (int *)malloc(sizeof(int)); 119*f4a2713aSLionel Sambuc CustomData *w = [CustomData somethingNoCopy:p length:sizeof(int) freeWhenDone:0]; // expected-warning{{leak}} 120*f4a2713aSLionel Sambuc} 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel Sambuc// Test CF/NS...NoCopy. PR12100: Pointers can escape when custom deallocators are provided. 123*f4a2713aSLionel Sambucvoid testNSDatafFreeWhenDone(NSUInteger dataLength) { 124*f4a2713aSLionel Sambuc CFStringRef str; 125*f4a2713aSLionel Sambuc char *bytes = (char*)malloc(12); 126*f4a2713aSLionel Sambuc str = CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0); // no warning 127*f4a2713aSLionel Sambuc CFRelease(str); // default allocator also frees bytes 128*f4a2713aSLionel Sambuc} 129*f4a2713aSLionel Sambuc 130*f4a2713aSLionel Sambucvoid stringWithExternalContentsExample(void) { 131*f4a2713aSLionel Sambuc#define BufferSize 1000 132*f4a2713aSLionel Sambuc CFMutableStringRef mutStr; 133*f4a2713aSLionel Sambuc UniChar *myBuffer; 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc myBuffer = (UniChar *)malloc(BufferSize * sizeof(UniChar)); 136*f4a2713aSLionel Sambuc 137*f4a2713aSLionel Sambuc mutStr = CFStringCreateMutableWithExternalCharactersNoCopy(0, myBuffer, 0, BufferSize, kCFAllocatorNull); // expected-warning{{leak}} 138*f4a2713aSLionel Sambuc 139*f4a2713aSLionel Sambuc CFRelease(mutStr); 140*f4a2713aSLionel Sambuc //free(myBuffer); 141*f4a2713aSLionel Sambuc} 142*f4a2713aSLionel Sambuc 143*f4a2713aSLionel Sambuc// PR12101 : pointers can escape through custom deallocators set on creation of a container. 144*f4a2713aSLionel Sambucvoid TestCallbackReleasesMemory(CFDictionaryKeyCallBacks keyCallbacks) { 145*f4a2713aSLionel Sambuc void *key = malloc(12); 146*f4a2713aSLionel Sambuc void *val = malloc(12); 147*f4a2713aSLionel Sambuc CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallbacks, &kCFTypeDictionaryValueCallBacks); 148*f4a2713aSLionel Sambuc CFDictionarySetValue(x, key, val); 149*f4a2713aSLionel Sambuc return;// no-warning 150*f4a2713aSLionel Sambuc} 151*f4a2713aSLionel Sambuc 152*f4a2713aSLionel SambucNSData *radar10976702() { 153*f4a2713aSLionel Sambuc void *bytes = malloc(10); 154*f4a2713aSLionel Sambuc return [NSData dataWithBytesNoCopy:bytes length:10]; // no-warning 155*f4a2713aSLionel Sambuc} 156*f4a2713aSLionel Sambuc 157*f4a2713aSLionel Sambucvoid testBlocks() { 158*f4a2713aSLionel Sambuc int *x= (int*)malloc(sizeof(int)); 159*f4a2713aSLionel Sambuc int (^myBlock)(int) = ^(int num) { 160*f4a2713aSLionel Sambuc free(x); 161*f4a2713aSLionel Sambuc return num; 162*f4a2713aSLionel Sambuc }; 163*f4a2713aSLionel Sambuc myBlock(3); 164*f4a2713aSLionel Sambuc} 165*f4a2713aSLionel Sambuc 166*f4a2713aSLionel Sambuc// Test NSMapInsert. 167*f4a2713aSLionel Sambuc@interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration> 168*f4a2713aSLionel Sambuc@end 169*f4a2713aSLionel Sambucextern void *NSMapGet(NSMapTable *table, const void *key); 170*f4a2713aSLionel Sambucextern void NSMapInsert(NSMapTable *table, const void *key, const void *value); 171*f4a2713aSLionel Sambucextern void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value); 172*f4a2713aSLionel Sambucchar *strdup(const char *s); 173*f4a2713aSLionel Sambuc 174*f4a2713aSLionel SambucNSString * radar11152419(NSString *string1, NSMapTable *map) { 175*f4a2713aSLionel Sambuc const char *strkey = "key"; 176*f4a2713aSLionel Sambuc NSString *string = ( NSString *)NSMapGet(map, strkey); 177*f4a2713aSLionel Sambuc if (!string) { 178*f4a2713aSLionel Sambuc string = [string1 copy]; 179*f4a2713aSLionel Sambuc NSMapInsert(map, strdup(strkey), (void*)string); // no warning 180*f4a2713aSLionel Sambuc NSMapInsertKnownAbsent(map, strdup(strkey), (void*)string); // no warning 181*f4a2713aSLionel Sambuc } 182*f4a2713aSLionel Sambuc return string; 183*f4a2713aSLionel Sambuc} 184*f4a2713aSLionel Sambuc 185*f4a2713aSLionel Sambuc// Test that we handle pointer escaping through OSAtomicEnqueue. 186*f4a2713aSLionel Sambuctypedef volatile struct { 187*f4a2713aSLionel Sambuc void *opaque1; 188*f4a2713aSLionel Sambuc long opaque2; 189*f4a2713aSLionel Sambuc} OSQueueHead; 190*f4a2713aSLionel Sambucvoid OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import)); 191*f4a2713aSLionel Sambucstatic inline void radar11111210(OSQueueHead *pool) { 192*f4a2713aSLionel Sambuc void *newItem = malloc(4); 193*f4a2713aSLionel Sambuc OSAtomicEnqueue(pool, newItem, 4); 194*f4a2713aSLionel Sambuc} 195*f4a2713aSLionel Sambuc 196*f4a2713aSLionel Sambuc// Pointer might escape through CGDataProviderCreateWithData (radar://11187558). 197*f4a2713aSLionel Sambuctypedef struct CGDataProvider *CGDataProviderRef; 198*f4a2713aSLionel Sambuctypedef void (*CGDataProviderReleaseDataCallback)(void *info, const void *data, 199*f4a2713aSLionel Sambuc size_t size); 200*f4a2713aSLionel Sambucextern CGDataProviderRef CGDataProviderCreateWithData(void *info, 201*f4a2713aSLionel Sambuc const void *data, size_t size, 202*f4a2713aSLionel Sambuc CGDataProviderReleaseDataCallback releaseData) 203*f4a2713aSLionel Sambuc __attribute__((visibility("default"))); 204*f4a2713aSLionel Sambucvoid *calloc(size_t, size_t); 205*f4a2713aSLionel Sambuc 206*f4a2713aSLionel Sambucstatic void releaseDataCallback (void *info, const void *data, size_t size) { 207*f4a2713aSLionel Sambuc#pragma unused (info, size) 208*f4a2713aSLionel Sambuc free((void*)data); 209*f4a2713aSLionel Sambuc} 210*f4a2713aSLionel Sambucvoid testCGDataProviderCreateWithData() { 211*f4a2713aSLionel Sambuc void* b = calloc(8, 8); 212*f4a2713aSLionel Sambuc CGDataProviderRef p = CGDataProviderCreateWithData(0, b, 8*8, releaseDataCallback); 213*f4a2713aSLionel Sambuc} 214*f4a2713aSLionel Sambuc 215*f4a2713aSLionel Sambuc// Assume that functions which take a function pointer can free memory even if 216*f4a2713aSLionel Sambuc// they are defined in system headers and take the const pointer to the 217*f4a2713aSLionel Sambuc// allocated memory. (radar://11160612) 218*f4a2713aSLionel Sambucextern CGDataProviderRef UnknownFunWithCallback(void *info, 219*f4a2713aSLionel Sambuc const void *data, size_t size, 220*f4a2713aSLionel Sambuc CGDataProviderReleaseDataCallback releaseData) 221*f4a2713aSLionel Sambuc __attribute__((visibility("default"))); 222*f4a2713aSLionel Sambucvoid testUnknownFunWithCallBack() { 223*f4a2713aSLionel Sambuc void* b = calloc(8, 8); 224*f4a2713aSLionel Sambuc CGDataProviderRef p = UnknownFunWithCallback(0, b, 8*8, releaseDataCallback); 225*f4a2713aSLionel Sambuc} 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel Sambuc// Test blocks. 228*f4a2713aSLionel Sambucvoid acceptBlockParam(void *, void (^block)(void *), unsigned); 229*f4a2713aSLionel Sambucvoid testCallWithBlockCallback() { 230*f4a2713aSLionel Sambuc void *l = malloc(12); 231*f4a2713aSLionel Sambuc acceptBlockParam(l, ^(void *i) { free(i); }, sizeof(char *)); 232*f4a2713aSLionel Sambuc} 233*f4a2713aSLionel Sambuc 234*f4a2713aSLionel Sambuc// Test blocks in system headers. 235*f4a2713aSLionel Sambucvoid testCallWithBlockCallbackInSystem() { 236*f4a2713aSLionel Sambuc void *l = malloc(12); 237*f4a2713aSLionel Sambuc SystemHeaderFunctionWithBlockParam(l, ^(void *i) { free(i); }, sizeof(char *)); 238*f4a2713aSLionel Sambuc} 239*f4a2713aSLionel Sambuc 240*f4a2713aSLionel Sambuc// Test escape into NSPointerArray. radar://11691035, PR13140 241*f4a2713aSLionel Sambucvoid foo(NSPointerArray* pointerArray) { 242*f4a2713aSLionel Sambuc 243*f4a2713aSLionel Sambuc void* p1 = malloc (1024); 244*f4a2713aSLionel Sambuc if (p1) { 245*f4a2713aSLionel Sambuc [pointerArray addPointer:p1]; 246*f4a2713aSLionel Sambuc } 247*f4a2713aSLionel Sambuc 248*f4a2713aSLionel Sambuc void* p2 = malloc (1024); 249*f4a2713aSLionel Sambuc if (p2) { 250*f4a2713aSLionel Sambuc [pointerArray insertPointer:p2 atIndex:1]; 251*f4a2713aSLionel Sambuc } 252*f4a2713aSLionel Sambuc 253*f4a2713aSLionel Sambuc void* p3 = malloc (1024); 254*f4a2713aSLionel Sambuc if (p3) { 255*f4a2713aSLionel Sambuc [pointerArray replacePointerAtIndex:1 withPointer:p3]; 256*f4a2713aSLionel Sambuc } 257*f4a2713aSLionel Sambuc 258*f4a2713aSLionel Sambuc // Freeing the buffer is allowed. 259*f4a2713aSLionel Sambuc void* buffer = [pointerArray pointerAtIndex:0]; 260*f4a2713aSLionel Sambuc free(buffer); 261*f4a2713aSLionel Sambuc} 262*f4a2713aSLionel Sambuc 263*f4a2713aSLionel Sambucvoid noCrashOnVariableArgumentSelector() { 264*f4a2713aSLionel Sambuc NSMutableString *myString = [NSMutableString stringWithString:@"some text"]; 265*f4a2713aSLionel Sambuc [myString appendFormat:@"some text = %d", 3]; 266*f4a2713aSLionel Sambuc} 267*f4a2713aSLionel Sambuc 268*f4a2713aSLionel Sambucvoid test12365078_check() { 269*f4a2713aSLionel Sambuc unichar *characters = (unichar*)malloc(12); 270*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 271*f4a2713aSLionel Sambuc if (!string) free(characters); // no-warning 272*f4a2713aSLionel Sambuc} 273*f4a2713aSLionel Sambuc 274*f4a2713aSLionel Sambucvoid test12365078_nocheck() { 275*f4a2713aSLionel Sambuc unichar *characters = (unichar*)malloc(12); 276*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 277*f4a2713aSLionel Sambuc} 278*f4a2713aSLionel Sambuc 279*f4a2713aSLionel Sambucvoid test12365078_false_negative() { 280*f4a2713aSLionel Sambuc unichar *characters = (unichar*)malloc(12); 281*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 282*f4a2713aSLionel Sambuc if (!string) {;} 283*f4a2713aSLionel Sambuc} 284*f4a2713aSLionel Sambuc 285*f4a2713aSLionel Sambucvoid test12365078_no_malloc(unichar *characters) { 286*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 287*f4a2713aSLionel Sambuc if (!string) {free(characters);} 288*f4a2713aSLionel Sambuc} 289*f4a2713aSLionel Sambuc 290*f4a2713aSLionel SambucNSString *test12365078_no_malloc_returnValue(unichar *characters) { 291*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 292*f4a2713aSLionel Sambuc if (!string) { 293*f4a2713aSLionel Sambuc return 0; // no-warning 294*f4a2713aSLionel Sambuc } 295*f4a2713aSLionel Sambuc return string; 296*f4a2713aSLionel Sambuc} 297*f4a2713aSLionel Sambuc 298*f4a2713aSLionel Sambucvoid test12365078_nocheck_nomalloc(unichar *characters) { 299*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 300*f4a2713aSLionel Sambuc free(characters); // expected-warning {{Attempt to free non-owned memory}} 301*f4a2713aSLionel Sambuc} 302*f4a2713aSLionel Sambuc 303*f4a2713aSLionel Sambucvoid test12365078_nested(unichar *characters) { 304*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 305*f4a2713aSLionel Sambuc if (!string) { 306*f4a2713aSLionel Sambuc NSString *string2 = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 307*f4a2713aSLionel Sambuc if (!string2) { 308*f4a2713aSLionel Sambuc NSString *string3 = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 309*f4a2713aSLionel Sambuc if (!string3) { 310*f4a2713aSLionel Sambuc NSString *string4 = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 311*f4a2713aSLionel Sambuc if (!string4) 312*f4a2713aSLionel Sambuc free(characters); 313*f4a2713aSLionel Sambuc } 314*f4a2713aSLionel Sambuc } 315*f4a2713aSLionel Sambuc } 316*f4a2713aSLionel Sambuc} 317*f4a2713aSLionel Sambuc 318*f4a2713aSLionel Sambucvoid test12365078_check_positive() { 319*f4a2713aSLionel Sambuc unichar *characters = (unichar*)malloc(12); 320*f4a2713aSLionel Sambuc NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; 321*f4a2713aSLionel Sambuc if (string) free(characters); // expected-warning{{Attempt to free non-owned memory}} 322*f4a2713aSLionel Sambuc} 323