Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -350,6 +350,9 @@ return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed)); } + ProgramStateRef setDead(SymbolRef Sym) const; + bool isDead(SymbolRef Sym) const; + //==---------------------------------------------------------------------==// // Accessing the Generic Data Map (GDM). //==---------------------------------------------------------------------==// Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -20,6 +20,7 @@ #include "clang/Analysis/AnalysisContext.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" @@ -542,6 +543,8 @@ return SE->getType(); } + ProgramStateRef notifyBind(ProgramStateRef state, const MemRegion *MR); + /// \brief Add artificial symbol dependency. /// /// The dependent symbol should stay alive as long as the primary is alive. @@ -572,6 +575,7 @@ const StackFrameContext *LCtx; const Stmt *Loc; + ProgramStateRef state; SymbolManager& SymMgr; StoreRef reapedStore; llvm::DenseMap includedRegionCache; @@ -584,10 +588,8 @@ /// considered live. /// If the stack frame context is NULL, everything on stack is considered /// dead. - SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr, - StoreManager &storeMgr) - : LCtx(Ctx), Loc(s), SymMgr(symmgr), - reapedStore(nullptr, storeMgr) {} + SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, + ProgramStateRef currentState); ~SymbolReaper() {} Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -262,6 +262,8 @@ ArrayRef Explicits, ArrayRef Regions, const CallEvent *Call) { + for (auto I = Regions.begin(), E = Regions.end(); I != E; I++) + state = getSymbolManager().notifyBind(state, *I); return getCheckerManager().runCheckersForRegionChanges(state, invalidated, Explicits, Regions, Call); } @@ -357,7 +359,7 @@ } const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr; - SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager()); + SymbolReaper SymReaper(SFC, ReferenceStmt, CleanedState); getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); Index: lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- lib/StaticAnalyzer/Core/ProgramState.cpp +++ lib/StaticAnalyzer/Core/ProgramState.cpp @@ -785,3 +785,16 @@ assert(NewState); return NewState; } + +/// The GDM component containing symbols that were invalidated by direct +/// binding to their regions +REGISTER_TRAIT_WITH_PROGRAMSTATE(OverwrittenSymbols, + llvm::ImmutableSet) + +ProgramStateRef ProgramState::setDead(SymbolRef Sym) const { + return add(Sym); +} + +bool ProgramState::isDead(SymbolRef Sym) const { + return contains(Sym); +} Index: lib/StaticAnalyzer/Core/SymbolManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/SymbolManager.cpp +++ lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" @@ -304,6 +305,18 @@ return cast(data); } +ProgramStateRef SymbolManager::notifyBind(ProgramStateRef state, + const MemRegion *MR) { + if (const TypedValueRegion* R = dyn_cast(MR)) { + llvm::FoldingSetNodeID profile; + SymbolRegionValue::Profile(profile, R); + void *InsertPos; + if (SymExpr *Sym = DataSet.FindNodeOrInsertPos(profile, InsertPos)) + return state->setDead(Sym); + } + return state; +} + QualType SymbolConjured::getType() const { return T; } @@ -365,6 +378,12 @@ return I->second; } +SymbolReaper::SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, + ProgramStateRef currentState) + : LCtx(Ctx), Loc(s), state(currentState), SymMgr(state->getSymbolManager()), + reapedStore(nullptr, state->getStateManager().getStoreManager()) {} + + void SymbolReaper::markDependentsLive(SymbolRef sym) { // Do not mark dependents more then once. SymbolMapTy::iterator LI = TheLiving.find(sym); @@ -446,9 +465,11 @@ bool KnownLive; switch (sym->getKind()) { - case SymExpr::RegionValueKind: - KnownLive = isLiveRegion(cast(sym)->getRegion()); + case SymExpr::RegionValueKind: { + const SymbolRegionValue *SRV = cast(sym); + KnownLive = isLiveRegion(SRV->getRegion()) && !state->isDead(sym); break; + } case SymExpr::ConjuredKind: KnownLive = false; break;