r359263 - [analyzer] RetainCount: Allow offsets in return values.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 25 19:05:15 PDT 2019


Author: dergachev
Date: Thu Apr 25 19:05:15 2019
New Revision: 359263

URL: http://llvm.org/viewvc/llvm-project?rev=359263&view=rev
Log:
[analyzer] RetainCount: Allow offsets in return values.

Because RetainCountChecker has custom "local" reasoning about escapes,
it has a separate facility to deal with tracked symbols at end of analysis
and check them for leaks regardless of whether they're dead or not.
This facility iterates over the list of tracked symbols and reports
them as leaks, but it needs to treat the return value specially.

Some custom allocators tend to return the value with an offset, storing
extra metadata at the beginning of the buffer. In this case the return value
would be a non-base region. In order to avoid false positives, we still need to
find the original symbol within the return value, otherwise it'll be unable
to match it to the item in the list of tracked symbols.

Differential Revision: https://reviews.llvm.org/D60991

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
    cfe/trunk/test/Analysis/retain-release.mm

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=359263&r1=359262&r2=359263&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Thu Apr 25 19:05:15 2019
@@ -970,8 +970,10 @@ ExplodedNode * RetainCountChecker::proce
     return Pred;
 
   ProgramStateRef state = C.getState();
-  SymbolRef Sym =
-    state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
+  // We need to dig down to the symbolic base here because various
+  // custom allocators do sometimes return the symbol with an offset.
+  SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
+                      .getAsLocSymbol(/*IncludeBaseRegions=*/true);
   if (!Sym)
     return Pred;
 

Modified: cfe/trunk/test/Analysis/retain-release.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.mm?rev=359263&r1=359262&r2=359263&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.mm (original)
+++ cfe/trunk/test/Analysis/retain-release.mm Thu Apr 25 19:05:15 2019
@@ -515,3 +515,35 @@ void foo() {
 }
 
 }
+
+namespace reinterpret_casts {
+
+void *foo() {
+  void *p = const_cast<void *>(
+      reinterpret_cast<const void *>(CFArrayCreate(0, 0, 0, 0)));
+  void *q = reinterpret_cast<void *>(
+      reinterpret_cast<char *>(p) + 1);
+  // FIXME: Should warn about a leak here. The function should return at +0,
+  // but it returns at +1 instead.
+  return q;
+}
+
+void *fooCreate() {
+  void *p = const_cast<void *>(
+      reinterpret_cast<const void *>(CFArrayCreate(0, 0, 0, 0)));
+  void *q = reinterpret_cast<void *>(
+      reinterpret_cast<char *>(p) + 1);
+  // The function follows the Create Rule.
+  return q; // no-warning
+}
+
+void *fooBar() CF_RETURNS_RETAINED {
+  void *p = const_cast<void *>(
+      reinterpret_cast<const void *>(CFArrayCreate(0, 0, 0, 0)));
+  void *q = reinterpret_cast<void *>(
+      reinterpret_cast<char *>(p) + 1);
+  // The function follows the Create Rule.
+  return q; // no-warning
+}
+
+}




More information about the cfe-commits mailing list