From: Anna Zaks Date: Mon, 5 Mar 2012 17:42:10 +0000 (+0000) Subject: [analyzer] Malloc should assume that ownership is transfered when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb7f76f285faa4c21d299f2bce8f55de3f71e548;p=clang [analyzer] Malloc should assume that ownership is transfered when calling an ObjC method ending with 'NoCopy'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152037 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index b74317cc98..4309045459 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1108,7 +1108,7 @@ bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call, if (FName.equals("pthread_setspecific")) return false; - // White list the 'XXXNoCopy' ObjC Methods. + // White list the 'XXXNoCopy' ObjC functions. if (FName.endswith("NoCopy")) { // Look for the deallocator argument. We know that the memory ownership // is not transfered only if the deallocator argument is @@ -1176,9 +1176,18 @@ bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call, if (S.getNameForSlot(i).equals("freeWhenDone")) { if (Call->getArgSVal(i).isConstant(1)) return false; + else + return true; } } + // If the first selector ends with NoCopy, assume that the ownership is + // transfered as well. + // Ex: [NSData dataWithBytesNoCopy:bytes length:10]; + if (S.getNameForSlot(0).endswith("NoCopy")) { + return false; + } + // Otherwise, assume that the function does not free memory. // Most system calls, do not free the memory. return true; diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm index 38667fd3e1..31db5ced15 100644 --- a/test/Analysis/malloc.mm +++ b/test/Analysis/malloc.mm @@ -91,3 +91,9 @@ void TestCallbackReleasesMemory(CFDictionaryKeyCallBacks keyCallbacks) { CFDictionarySetValue(x, key, val); return;// no-warning } + +NSData *radar10976702() { + void *bytes = malloc(10); + return [NSData dataWithBytesNoCopy:bytes length:10]; // no-warning +} +