From fb05094b526217ff2c7702d9236d69a3fbe268fc Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Tue, 17 Sep 2013 00:53:28 +0000 Subject: [PATCH] [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 --- .../StaticAnalyzer/Checkers/RetainCountChecker.cpp | 10 ++++++++++ clang/test/Analysis/retain-release.m | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 7a97ce52c687..d2a4448a5fd7 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(loc.getAsRegion())) { + const VarDecl *VD = LVR->getDecl(); + if (VD->getAttr()) { + 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 bb4a1d169d24..eda0c4ee78ea 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: diagnostics // CHECK-NEXT: