rnkovacs created this revision.
rnkovacs added reviewers: NoQ, xazax.hun, george.karpenkov.
Herald added subscribers: a.sidorin, dkrupp, szepet, baloghadamsoftware, 
whisperity.

Symbols are cleaned up from the program state map when they go out of scope. 
(This will need to be done individually when the collection of multiple symbols 
for one region will be supported.)
Regions are cleaned up when the corresponding object is destroyed.


Repository:
  rC Clang

https://reviews.llvm.org/D47416

Files:
  lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp


Index: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
+++ lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
@@ -26,7 +26,8 @@
 
 namespace {
 
-class DanglingInternalBufferChecker : public Checker<check::PostCall> {
+class DanglingInternalBufferChecker : public Checker<check::DeadSymbols,
+                                                     check::PostCall> {
   CallDescription CStrFn;
 
 public:
@@ -36,6 +37,9 @@
   /// corresponding string object region in the ProgramState. Mark the symbol
   /// released if the string object is destroyed.
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+
+  /// Clean up the ProgramState map.
+  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
 };
 
 } // end anonymous namespace
@@ -73,12 +77,28 @@
       const SymbolRef *StrBufferPtr = State->get<RawPtrMap>(TypedR);
       const Expr *Origin = Call.getOriginExpr();
       State = allocation_state::markReleased(State, *StrBufferPtr, Origin);
+      State = State->remove<RawPtrMap>(TypedR);
       C.addTransition(State);
       return;
     }
   }
 }
 
+void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper &SymReaper,
+                                                     CheckerContext &C) const {
+  if (!SymReaper.hasDeadSymbols())
+    return;
+
+  ProgramStateRef State = C.getState();
+  RawPtrMapTy RPM = State->get<RawPtrMap>();
+  for (const auto Region : RPM) {
+    if (SymReaper.isDead(Region.second))
+      State = State->remove<RawPtrMap>(Region.first);
+  }
+
+  C.addTransition(State);
+}
+
 void ento::registerDanglingInternalBufferChecker(CheckerManager &Mgr) {
   registerNewDeleteChecker(Mgr);
   Mgr.registerChecker<DanglingInternalBufferChecker>();


Index: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
+++ lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
@@ -26,7 +26,8 @@
 
 namespace {
 
-class DanglingInternalBufferChecker : public Checker<check::PostCall> {
+class DanglingInternalBufferChecker : public Checker<check::DeadSymbols,
+                                                     check::PostCall> {
   CallDescription CStrFn;
 
 public:
@@ -36,6 +37,9 @@
   /// corresponding string object region in the ProgramState. Mark the symbol
   /// released if the string object is destroyed.
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+
+  /// Clean up the ProgramState map.
+  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
 };
 
 } // end anonymous namespace
@@ -73,12 +77,28 @@
       const SymbolRef *StrBufferPtr = State->get<RawPtrMap>(TypedR);
       const Expr *Origin = Call.getOriginExpr();
       State = allocation_state::markReleased(State, *StrBufferPtr, Origin);
+      State = State->remove<RawPtrMap>(TypedR);
       C.addTransition(State);
       return;
     }
   }
 }
 
+void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper &SymReaper,
+                                                     CheckerContext &C) const {
+  if (!SymReaper.hasDeadSymbols())
+    return;
+
+  ProgramStateRef State = C.getState();
+  RawPtrMapTy RPM = State->get<RawPtrMap>();
+  for (const auto Region : RPM) {
+    if (SymReaper.isDead(Region.second))
+      State = State->remove<RawPtrMap>(Region.first);
+  }
+
+  C.addTransition(State);
+}
+
 void ento::registerDanglingInternalBufferChecker(CheckerManager &Mgr) {
   registerNewDeleteChecker(Mgr);
   Mgr.registerChecker<DanglingInternalBufferChecker>();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to