]> granicus.if.org Git - clang/commitdiff
[analyzer] Allow pointers to escape into NSPointerArray.
authorAnna Zaks <ganna@apple.com>
Tue, 19 Jun 2012 05:10:32 +0000 (05:10 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 19 Jun 2012 05:10:32 +0000 (05:10 +0000)
(Fixes radar://11691035 PR13140)

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

lib/StaticAnalyzer/Checkers/MallocChecker.cpp
test/Analysis/malloc.mm
test/Analysis/system-header-simulator-objc.h

index 1adcca03fdcf91b8873258a8050f89c7fcf2789e..255225467f058f1f1fda05a92a1f2f46b7aafd90 100644 (file)
@@ -1384,6 +1384,16 @@ bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call,
       return false;
     }
 
+    // If the first selector starts with addPointer, insertPointer,
+    // or replacePointer, assume we are dealing with NSPointerArray or similar.
+    // This is similar to C++ containers (vector); we still might want to check
+    // that the pointers get freed, by following the container itself.
+    if (S.getNameForSlot(0).startswith("addPointer") ||
+        S.getNameForSlot(0).startswith("insertPointer") ||
+        S.getNameForSlot(0).startswith("replacePointer")) {
+      return false;
+    }
+
     // If the call has a callback as an argument, assume the memory
     // can be freed.
     if (Call->hasNonZeroCallbackArg())
index ef1adda5a128c6f97874f72708c47b1b74e751d2..855892da2bfa78c66e115f5b0cf82686fc6ddfee 100644 (file)
@@ -178,4 +178,27 @@ void testCallWithBlockCallback() {
 void testCallWithBlockCallbackInSystem() {
   void *l = malloc(12);
   SystemHeaderFunctionWithBlockParam(l, ^(void *i) { free(i); }, sizeof(char *));
+}
+
+// Test escape into NSPointerArray. radar://11691035, PR13140
+void foo(NSPointerArray* pointerArray) {
+  
+  void* p1 = malloc (1024);
+  if (p1) {
+    [pointerArray addPointer:p1];
+  }
+
+  void* p2 = malloc (1024);
+  if (p2) {
+    [pointerArray insertPointer:p2 atIndex:1];
+  }
+
+  void* p3 = malloc (1024);
+  if (p3) {
+    [pointerArray replacePointerAtIndex:1 withPointer:p3];
+  }
+
+  // Freeing the buffer is allowed.
+  void* buffer = [pointerArray pointerAtIndex:0];
+  free(buffer);
 }
\ No newline at end of file
index 4626a4ec4f5b1ef48a3a2677acc8db92f01f04a1..20a26cdbaaa7b44a2bce91e3244f79b2af36e780 100644 (file)
@@ -114,3 +114,11 @@ extern CFStringRef CFStringCreateWithCStringNoCopy(CFAllocatorRef alloc, const c
 extern void CFStringAppend(CFMutableStringRef theString, CFStringRef appendedString);
 
 void SystemHeaderFunctionWithBlockParam(void *, void (^block)(void *), unsigned);
+
+@interface NSPointerArray : NSObject <NSFastEnumeration, NSCopying, NSCoding>
+- (void)addPointer:(void *)pointer;
+- (void)insertPointer:(void *)item atIndex:(NSUInteger)index;
+- (void)replacePointerAtIndex:(NSUInteger)index withPointer:(void *)item;
+- (void *)pointerAtIndex:(NSUInteger)index;
+@end
+