aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReka Kovacs <rekanikolett@gmail.com>2018-06-09 21:08:27 +0000
committerReka Kovacs <rekanikolett@gmail.com>2018-06-09 21:08:27 +0000
commit79d87e56ee55943d1d1b9f50fdf8374bc858e782 (patch)
treeeffb0751e9adb470931548fd09d7d193a4441d2e
parent694f835265f40cbfbb02bd64ee766d1acd879dc6 (diff)
[analyzer] Clean up the program state map of DanglingInternalBufferChecker.
Symbols are cleaned up from the program state map when they go out of scope. Memory regions are cleaned up when the corresponding object is destroyed, and additionally in 'checkDeadSymbols' in case destructor modeling was incomplete. Differential Revision: https://reviews.llvm.org/D47416 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334352 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp b/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
index e7884ee104..18f0a22e4a 100644
--- a/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
@@ -26,7 +26,8 @@ using namespace ento;
namespace {
-class DanglingInternalBufferChecker : public Checker<check::PostCall> {
+class DanglingInternalBufferChecker : public Checker<check::DeadSymbols,
+ check::PostCall> {
CallDescription CStrFn;
public:
@@ -36,6 +37,9 @@ public:
/// 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
@@ -76,12 +80,29 @@ void DanglingInternalBufferChecker::checkPostCall(const CallEvent &Call,
// FIXME: What if Origin is null?
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 {
+ ProgramStateRef State = C.getState();
+ RawPtrMapTy RPM = State->get<RawPtrMap>();
+ for (const auto Entry : RPM) {
+ if (!SymReaper.isLive(Entry.second))
+ State = State->remove<RawPtrMap>(Entry.first);
+ if (!SymReaper.isLiveRegion(Entry.first)) {
+ // Due to incomplete destructor support, some dead regions might still
+ // remain in the program state map. Clean them up.
+ State = State->remove<RawPtrMap>(Entry.first);
+ }
+ }
+ C.addTransition(State);
+}
+
void ento::registerDanglingInternalBufferChecker(CheckerManager &Mgr) {
registerNewDeleteChecker(Mgr);
Mgr.registerChecker<DanglingInternalBufferChecker>();