summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-09-17 00:53:28 +0000
committerAnna Zaks <ganna@apple.com>2013-09-17 00:53:28 +0000
commitfb05094b526217ff2c7702d9236d69a3fbe268fc (patch)
tree961a93ec4a2e656bb033b6253b4170166e4e24cb
parent9fc443aaedafb512108bd2ef3f48df570efee3b3 (diff)
downloadbcm5719-llvm-fb05094b526217ff2c7702d9236d69a3fbe268fc.tar.gz
bcm5719-llvm-fb05094b526217ff2c7702d9236d69a3fbe268fc.zip
[analyzer] Stop tracking the objects with attribute cleanup in the RetainCountChecker.
This suppresses false positive leaks. We stop tracking a value if it is assigned to a variable declared with a cleanup attribute. llvm-svn: 190835
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp10
-rw-r--r--clang/test/Analysis/retain-release.m14
2 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 7a97ce52c68..d2a4448a5fd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -3356,6 +3356,16 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
}
}
+ // If we are storing the value into an auto function scope variable annotated
+ // with (__attribute__((cleanup))), stop tracking the value to avoid leak
+ // false positives.
+ if (const VarRegion *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
+ const VarDecl *VD = LVR->getDecl();
+ if (VD->getAttr<CleanupAttr>()) {
+ escapes = true;
+ }
+ }
+
// If our store can represent the binding and we aren't storing to something
// that doesn't have local storage then just return and have the simulation
// state continue as is.
diff --git a/clang/test/Analysis/retain-release.m b/clang/test/Analysis/retain-release.m
index bb4a1d169d2..eda0c4ee78e 100644
--- a/clang/test/Analysis/retain-release.m
+++ b/clang/test/Analysis/retain-release.m
@@ -2022,6 +2022,20 @@ void rdar13783514(xpc_connection_t connection) {
xpc_connection_set_finalizer_f(connection, releaseAfterXPC);
} // no-warning
+// Do not report leaks when object is cleaned up with __attribute__((cleanup ..)).
+inline static void cleanupFunction(void *tp) {
+ CFTypeRef x = *(CFTypeRef *)tp;
+ if (x) {
+ CFRelease(x);
+ }
+}
+#define ADDCLEANUP __attribute__((cleanup(cleanupFunction)))
+void foo() {
+ ADDCLEANUP CFStringRef myString;
+ myString = CFStringCreateWithCString(0, "hello world", kCFStringEncodingUTF8);
+ ADDCLEANUP CFStringRef myString2 =
+ CFStringCreateWithCString(0, "hello world", kCFStringEncodingUTF8);
+}
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
OpenPOWER on IntegriCloud