[PATCH] D27409: [analyzer] RetainCountChecker: The callback in dispatch_data_create() doesn't free the return symbol.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 5 05:43:01 PST 2016


NoQ created this revision.
NoQ added reviewers: zaks.anna, dcoughlin.
NoQ added a subscriber: cfe-commits.

The hack that was previously applied to `CGBitmapContextCreateWithData()` is now extended to another function, `dispatch_data_create()`.

This function accepts a callback block, and the analyzer erroneously assumes that this callback may free up some data, which results in being unable to detect a leak of the `dispatch_data_t` object. In fact, the callback only frees the buffer that is passed into the function, but the returned object should be released separately unless in ARC mode.


https://reviews.llvm.org/D27409

Files:
  lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
  test/Analysis/dispatch-data-leak.m


Index: test/Analysis/dispatch-data-leak.m
===================================================================
--- /dev/null
+++ test/Analysis/dispatch-data-leak.m
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -w -triple x86_64-apple-macosx10.12.0 -fblocks -analyze -analyzer-checker=core,osx.cocoa,unix.Malloc -verify %s
+// RUN: %clang_cc1 -w -triple x86_64-apple-macosx10.12.0 -fblocks -fobjc-arc -analyze -analyzer-checker=core,osx.cocoa,unix.Malloc -verify %s
+
+#include "Inputs/system-header-simulator.h"
+#include "Inputs/system-header-simulator-objc.h"
+
+#define NON_ARC !__has_feature(objc_arc)
+
+#define DISPATCH_QUEUE_SERIAL NULL
+
+#define DISPATCH_DATA_DESTRUCTOR_DEFAULT NULL
+#define DISPATCH_DATA_DESTRUCTOR_FREE (_dispatch_data_destructor_free)
+#define DISPATCH_DATA_DESTRUCTOR_MUNMAP (_dispatch_data_destructor_munmap)
+
+#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
+#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED
+
+ at protocol OS_dispatch_data <NSObject>
+ at end
+ at protocol OS_dispatch_queue <NSObject>
+ at end
+ at protocol OS_dispatch_queue_attr <NSObject>
+ at end
+
+typedef NSObject<OS_dispatch_data> *dispatch_data_t;
+typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;
+typedef NSObject<OS_dispatch_queue_attr> *dispatch_queue_attr_t;
+
+typedef void (^dispatch_block_t)(void);
+
+dispatch_queue_t dispatch_get_main_queue(void);
+
+DISPATCH_RETURNS_RETAINED dispatch_queue_t
+dispatch_queue_create(const char *_Nullable label,
+                      dispatch_queue_attr_t _Nullable attr);
+
+DISPATCH_RETURNS_RETAINED dispatch_data_t
+dispatch_data_create(const void *buffer, size_t size,
+                     dispatch_queue_t _Nullable queue,
+                     dispatch_block_t _Nullable destructor);
+
+void clang_analyzer_printState();
+
+char buf[1024];
+void find_all_three_leaks() {
+  char *malloc_buf;
+  dispatch_data_t data;
+  dispatch_queue_t q;
+
+  malloc_buf = malloc(1024);
+  data = dispatch_data_create(buf, 1024, dispatch_get_main_queue(), ^{}); // expected-warning{{Potential leak of memory pointed to by 'malloc_buf'}}
+#if NON_ARC
+  // expected-warning at -2{{Potential leak of an object stored into 'data'}}
+#endif
+  q = dispatch_queue_create("hello", DISPATCH_QUEUE_SERIAL);
+#if NON_ARC
+  // expected-warning at -2{{Potential leak of an object stored into 'q'}}
+#endif
+}
Index: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -953,7 +953,8 @@
       if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) {
         // When the CGBitmapContext is deallocated, the callback here will free
         // the associated data buffer.
-        if (Name->isStr("CGBitmapContextCreateWithData"))
+        if (Name->isStr("CGBitmapContextCreateWithData") ||
+            Name->isStr("dispatch_data_create"))
           RE = S->getRetEffect();
       }
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27409.80258.patch
Type: text/x-patch
Size: 3026 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161205/176bfe63/attachment.bin>


More information about the cfe-commits mailing list