From 1484d0f12addf0d8aa08831adb63b8f56b8bd0f6 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Fri, 24 Jan 2020 18:38:57 +0300 Subject: [PATCH] [analyzer] PthreadLock: Implement dead region cleanup. Differential Revision: https://reviews.llvm.org/D37963 --- .../Checkers/PthreadLockChecker.cpp | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp index 66b78d76ce2..ed0fc0f98c2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -536,19 +536,24 @@ void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); - // TODO: Clean LockMap when a mutex region dies. - - DestroyRetValTy TrackedSymbols = State->get(); - for (DestroyRetValTy::iterator I = TrackedSymbols.begin(), - E = TrackedSymbols.end(); - I != E; ++I) { - const SymbolRef Sym = I->second; - const MemRegion *lockR = I->first; - bool IsSymDead = SymReaper.isDead(Sym); - // Remove the dead symbol from the return value symbols map. - if (IsSymDead) - State = resolvePossiblyDestroyedMutex(State, lockR, &Sym); + for (auto I : State->get()) { + // Once the return value symbol dies, no more checks can be performed + // against it. See if the return value was checked before this point. + // This would remove the symbol from the map as well. + if (SymReaper.isDead(I.second)) + State = resolvePossiblyDestroyedMutex(State, I.first, &I.second); } + + for (auto I : State->get()) { + // Stop tracking dead mutex regions as well. + if (!SymReaper.isLiveRegion(I.first)) + State = State->remove(I.first); + } + + // TODO: We probably need to clean up the lock stack as well. + // It is tricky though: even if the mutex cannot be unlocked anymore, + // it can still participate in lock order reversal resolution. + C.addTransition(State); }