]> granicus.if.org Git - clang/commitdiff
[analyzer] Malloc should assume that ownership is transfered when
authorAnna Zaks <ganna@apple.com>
Mon, 5 Mar 2012 17:42:10 +0000 (17:42 +0000)
committerAnna Zaks <ganna@apple.com>
Mon, 5 Mar 2012 17:42:10 +0000 (17:42 +0000)
calling an ObjC method ending with 'NoCopy'.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152037 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/MallocChecker.cpp
test/Analysis/malloc.mm

index b74317cc98b59b0fe86418393c41ec68286fca33..4309045459e35c3e38dc95ba93f288b42f84910a 100644 (file)
@@ -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;
index 38667fd3e11177a99619a7f042cffe630b24e76f..31db5ced15a1023dfbb185e84577cef057fb4d3e 100644 (file)
@@ -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
+}
+