From: Anna Zaks Date: Tue, 17 Sep 2013 00:53:28 +0000 (+0000) Subject: [analyzer] Stop tracking the objects with attribute cleanup in the RetainCountChecker. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73fa2525b4d8b9768dbc1e5a09976d6f9e568e23;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190835 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 7a97ce52c6..d2a4448a5f 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/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/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index bb4a1d169d..eda0c4ee78 100644 --- a/test/Analysis/retain-release.m +++ b/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: