[analyzer] Allow pointers escape through calls containing callback args.
(Since we don't have a generic pointer escape callback, modify
ExprEngineCallAndReturn as well as the malloc checker.)
llvm-svn: 156134
diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c
index 9c09051..f5bff4f 100644
--- a/clang/test/Analysis/malloc.c
+++ b/clang/test/Analysis/malloc.c
@@ -798,6 +798,27 @@
ptr = ptr; // expected-warning {{leak}}
}
+// Assume that functions which take a function pointer can free memory even if
+// they are defined in system headers and take the const pointer to the
+// allocated memory. (radar://11160612)
+int const_ptr_and_callback(int, const char*, int n, void(*)(void*));
+void r11160612_1() {
+ char *x = malloc(12);
+ const_ptr_and_callback(0, x, 12, free); // no - warning
+}
+
+// Null is passed as callback.
+void r11160612_2() {
+ char *x = malloc(12);
+ const_ptr_and_callback(0, x, 12, 0); // expected-warning {{leak}}
+}
+
+// Callback is passed to a function defined in a system header.
+void r11160612_4() {
+ char *x = malloc(12);
+ sqlite3_bind_text_my(0, x, 12, free); // no - warning
+}
+
// ----------------------------------------------------------------------------
// Below are the known false positives.
diff --git a/clang/test/Analysis/malloc.cpp b/clang/test/Analysis/malloc.cpp
index 8f80b2b..f36d8fc 100644
--- a/clang/test/Analysis/malloc.cpp
+++ b/clang/test/Analysis/malloc.cpp
@@ -14,3 +14,13 @@
Foo aFunction() {
return malloc(10);
}
+
+// Assume that functions which take a function pointer can free memory even if
+// they are defined in system headers and take the const pointer to the
+// allocated memory. (radar://11160612)
+// Test default parameter.
+int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = 0);
+void r11160612_3() {
+ char *x = (char*)malloc(12);
+ const_ptr_and_callback_def_param(0, x, 12);
+}
diff --git a/clang/test/Analysis/malloc.m b/clang/test/Analysis/malloc.m
index 6c94118..08206f3 100644
--- a/clang/test/Analysis/malloc.m
+++ b/clang/test/Analysis/malloc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class -fblocks %s
#include "system-header-simulator-objc.h"
@class NSString;
diff --git a/clang/test/Analysis/malloc.mm b/clang/test/Analysis/malloc.mm
index 3515a4f..ef1adda 100644
--- a/clang/test/Analysis/malloc.mm
+++ b/clang/test/Analysis/malloc.mm
@@ -153,4 +153,29 @@
void testCGDataProviderCreateWithData() {
void* b = calloc(8, 8);
CGDataProviderRef p = CGDataProviderCreateWithData(0, b, 8*8, releaseDataCallback);
+}
+
+// Assume that functions which take a function pointer can free memory even if
+// they are defined in system headers and take the const pointer to the
+// allocated memory. (radar://11160612)
+extern CGDataProviderRef UnknownFunWithCallback(void *info,
+ const void *data, size_t size,
+ CGDataProviderReleaseDataCallback releaseData)
+ __attribute__((visibility("default")));
+void testUnknownFunWithCallBack() {
+ void* b = calloc(8, 8);
+ CGDataProviderRef p = UnknownFunWithCallback(0, b, 8*8, releaseDataCallback);
+}
+
+// Test blocks.
+void acceptBlockParam(void *, void (^block)(void *), unsigned);
+void testCallWithBlockCallback() {
+ void *l = malloc(12);
+ acceptBlockParam(l, ^(void *i) { free(i); }, sizeof(char *));
+}
+
+// Test blocks in system headers.
+void testCallWithBlockCallbackInSystem() {
+ void *l = malloc(12);
+ SystemHeaderFunctionWithBlockParam(l, ^(void *i) { free(i); }, sizeof(char *));
}
\ No newline at end of file
diff --git a/clang/test/Analysis/system-header-simulator-objc.h b/clang/test/Analysis/system-header-simulator-objc.h
index 92d5899..4626a4e 100644
--- a/clang/test/Analysis/system-header-simulator-objc.h
+++ b/clang/test/Analysis/system-header-simulator-objc.h
@@ -112,3 +112,5 @@
extern CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocatorRef alloc, UniChar *chars, CFIndex numChars, CFIndex capacity, CFAllocatorRef externalCharactersAllocator);
extern CFStringRef CFStringCreateWithCStringNoCopy(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding, CFAllocatorRef contentsDeallocator);
extern void CFStringAppend(CFMutableStringRef theString, CFStringRef appendedString);
+
+void SystemHeaderFunctionWithBlockParam(void *, void (^block)(void *), unsigned);
diff --git a/clang/test/Analysis/system-header-simulator.h b/clang/test/Analysis/system-header-simulator.h
index 6212131..c910ad9 100644
--- a/clang/test/Analysis/system-header-simulator.h
+++ b/clang/test/Analysis/system-header-simulator.h
@@ -36,3 +36,4 @@
fpos_t (*)(void *, fpos_t, int),
int (*)(void *));
+int sqlite3_bind_text_my(int, const char*, int n, void(*)(void*));