[PATCH] D63093: [analyzer] WIP: MallocChecker: Release temporary CXXNewExpr

Csaba Dabis via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 10 13:11:51 PDT 2019


Charusso created this revision.
Charusso added reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus.
Charusso added a project: clang.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet.

-


Repository:
  rC Clang

https://reviews.llvm.org/D63093

Files:
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp


Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -156,21 +156,14 @@
 
 typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
 
-class MallocChecker : public Checker<check::DeadSymbols,
-                                     check::PointerEscape,
-                                     check::ConstPointerEscape,
-                                     check::PreStmt<ReturnStmt>,
-                                     check::EndFunction,
-                                     check::PreCall,
-                                     check::PostStmt<CallExpr>,
-                                     check::PostStmt<CXXNewExpr>,
-                                     check::NewAllocator,
-                                     check::PreStmt<CXXDeleteExpr>,
-                                     check::PostStmt<BlockExpr>,
-                                     check::PostObjCMessage,
-                                     check::Location,
-                                     eval::Assume>
-{
+class MallocChecker
+    : public Checker<check::DeadSymbols, check::PointerEscape,
+                     check::ConstPointerEscape, check::PreStmt<ReturnStmt>,
+                     check::EndFunction, check::PreCall,
+                     check::PostStmt<CallExpr>, check::PostStmt<CXXNewExpr>,
+                     check::PostStmt<CXXBindTemporaryExpr>, check::NewAllocator,
+                     check::PreStmt<CXXDeleteExpr>, check::PostStmt<BlockExpr>,
+                     check::PostObjCMessage, check::Location, eval::Assume> {
 public:
   MallocChecker()
       : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr),
@@ -211,6 +204,7 @@
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
+  void checkPostStmt(const CXXBindTemporaryExpr *BTE, CheckerContext &C) const;
   void checkNewAllocator(const CXXNewExpr *NE, SVal Target,
                          CheckerContext &C) const;
   void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
@@ -489,7 +483,8 @@
       bool IsReleased = (S && S->isReleased()) &&
                         (!SPrev || !SPrev->isReleased());
       assert(!IsReleased ||
-             (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt))) ||
+             (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt) ||
+                       isa<CXXBindTemporaryExpr>(Stmt))) ||
              (!Stmt && S->getAllocationFamily() == AF_InnerBuffer));
       return IsReleased;
     }
@@ -1103,6 +1098,34 @@
     processNewAllocation(NE, C, Target);
 }
 
+void MallocChecker::checkPostStmt(const CXXBindTemporaryExpr *BTE,
+                                  CheckerContext &C) const {
+  if (const auto *CE = dyn_cast<CXXConstructExpr>(BTE->getSubExpr())) {
+    if (CE->getNumArgs() == 0)
+      return;
+
+    // If we catch a 'CXXNewExpr' set it is released as it is temporary.
+    if (const auto *NE = dyn_cast<CXXNewExpr>(CE->getArg(0))) {
+      ProgramStateRef State = C.getState();
+      Optional<SVal> RetVal = C.getSVal(NE);
+
+      SymbolRef Sym = RetVal->getAsLocSymbol();
+      assert(Sym);
+
+      if (const RefState *RS = State->get<RegionState>(Sym))
+        if (RS->isReleased())
+          return;
+
+      // Set the symbol's state to Released.
+      State = State->set<RegionState>(
+          Sym, RefState::getReleased(NE->isArray() ? AF_CXXNewArray : AF_CXXNew,
+                                     NE));
+
+      C.addTransition(State);
+    }
+  }
+}
+
 // Sets the extent value of the MemRegion allocated by
 // new expression NE to its size in Bytes.
 //


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63093.203885.patch
Type: text/x-patch
Size: 3907 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190610/531c4b0e/attachment-0001.bin>


More information about the cfe-commits mailing list