r345099 - [analyzer] Trust summaries for OSObject::retain and OSObject::release

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 23 16:11:30 PDT 2018


Author: george.karpenkov
Date: Tue Oct 23 16:11:30 2018
New Revision: 345099

URL: http://llvm.org/viewvc/llvm-project?rev=345099&view=rev
Log:
[analyzer] Trust summaries for OSObject::retain and OSObject::release

Refactor the way in which summaries are consumed for safeMetaCast

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

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

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=345099&r1=345098&r2=345099&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Tue Oct 23 16:11:30 2018
@@ -776,31 +776,27 @@ bool RetainCountChecker::evalCall(const
 
   const LocationContext *LCtx = C.getLocationContext();
 
-  // Process OSDynamicCast: should just return the first argument.
-  // For now, tresting the cast as a no-op, and disregarding the case where
-  // the output becomes null due to the type mismatch.
-  if (FD->getNameAsString() == "safeMetaCast") {
-    state = state->BindExpr(CE, LCtx, 
-                            state->getSVal(CE->getArg(0), LCtx));
-    C.addTransition(state);
-    return true;
-  }
-
   // See if it's one of the specific functions we know how to eval.
   if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
     return false;
 
   // Bind the return value.
-  SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
-  if (RetVal.isUnknown() ||
-      (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+  // For now, all the functions which we can evaluate and which take
+  // at least one argument are identities.
+  if (CE->getNumArgs() >= 1) {
+    SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
+
     // If the receiver is unknown or the function has
     // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
     // return value.
-    SValBuilder &SVB = C.getSValBuilder();
-    RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+    if (RetVal.isUnknown() ||
+        (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+      SValBuilder &SVB = C.getSValBuilder();
+      RetVal =
+          SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+    }
+    state = state->BindExpr(CE, LCtx, RetVal, false);
   }
-  state = state->BindExpr(CE, LCtx, RetVal, false);
 
   C.addTransition(state);
   return true;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345099&r1=345098&r2=345099&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue Oct 23 16:11:30 2018
@@ -102,9 +102,6 @@ RetainSummaryManager::generateSummary(co
     return getPersistentStopSummary();
   }
 
-  // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the
-  // function's type.
-  const FunctionType *FT = FD->getType()->getAs<FunctionType>();
   const IdentifierInfo *II = FD->getIdentifier();
   if (!II)
     return getDefaultSummary();
@@ -115,7 +112,8 @@ RetainSummaryManager::generateSummary(co
   // down below.
   FName = FName.substr(FName.find_first_not_of('_'));
 
-  // Inspect the result type.
+  // Inspect the result type. Strip away any typedefs.
+  const auto *FT = FD->getType()->getAs<FunctionType>();
   QualType RetTy = FT->getReturnType();
   std::string RetTyName = RetTy.getAsString();
 
@@ -506,12 +504,6 @@ bool RetainSummaryManager::isTrustedRefe
 bool RetainSummaryManager::canEval(const CallExpr *CE,
                                    const FunctionDecl *FD,
                                    bool &hasTrustedImplementationAnnotation) {
-  // For now, we're only handling the functions that return aliases of their
-  // arguments: CFRetain (and its families).
-  // Eventually we should add other functions we can model entirely,
-  // such as CFRelease, which don't invalidate their arguments or globals.
-  if (CE->getNumArgs() != 1)
-    return false;
 
   IdentifierInfo *II = FD->getIdentifier();
   if (!II)
@@ -533,6 +525,13 @@ bool RetainSummaryManager::canEval(const
       return isRetain(FD, FName) || isAutorelease(FD, FName) ||
              isMakeCollectable(FName);
 
+    // Process OSDynamicCast: should just return the first argument.
+    // For now, treating the cast as a no-op, and disregarding the case where
+    // the output becomes null due to the type mismatch.
+    if (TrackOSObjects && FName == "safeMetaCast") {
+      return true;
+    }
+
     const FunctionDecl* FDD = FD->getDefinition();
     if (FDD && isTrustedReferenceCountImplementation(FDD)) {
       hasTrustedImplementationAnnotation = true;
@@ -540,6 +539,12 @@ bool RetainSummaryManager::canEval(const
     }
   }
 
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    const CXXRecordDecl *Parent = MD->getParent();
+    if (TrackOSObjects && Parent && isOSObjectSubclass(Parent))
+      return FName == "release" || FName == "retain";
+  }
+
   return false;
 
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345099&r1=345098&r2=345099&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Oct 23 16:11:30 2018
@@ -9,7 +9,7 @@ struct OSMetaClass;
 
 struct OSObject {
   virtual void retain();
-  virtual void release();
+  virtual void release() {};
   virtual ~OSObject(){}
 
   static OSObject *generateObject(int);




More information about the cfe-commits mailing list