diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h | 19 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SymbolManager.cpp | 31 |
2 files changed, 49 insertions, 1 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index 4fa294055a..dc3d15b259 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -91,6 +91,7 @@ public: }; typedef const SymbolData* SymbolRef; +typedef llvm::SmallVector<SymbolRef, 1> SymbolRefSmallVectorTy; /// A symbol representing the value of a MemRegion. class SymbolRegionValue : public SymbolData { @@ -357,8 +358,12 @@ public: class SymbolManager { typedef llvm::FoldingSet<SymExpr> DataSetTy; + typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy> SymbolDependTy; DataSetTy DataSet; + /// Stores the extra dependencies between symbols: the data should be kept + /// alive as long as the key is live. + SymbolDependTy SymbolDependencies; unsigned SymbolCounter; llvm::BumpPtrAllocator& BPAlloc; BasicValueFactory &BV; @@ -413,6 +418,16 @@ public: return SE->getType(Ctx); } + /// \brief Add artificial symbol dependency. + /// + /// The dependent symbol should stay alive as long as the primary is alive. + void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent); + + /// \brief Drop all user-added dependencies on the primary symbol. + void removeSymbolDependencies(const SymbolRef Primary); + + const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary); + ASTContext &getContext() { return Ctx; } BasicValueFactory &getBasicVals() { return BV; } }; @@ -495,6 +510,10 @@ public: /// \brief Set to the value of the symbolic store after /// StoreManager::removeDeadBindings has been called. void setReapedStore(StoreRef st) { reapedStore = st; } + +private: + /// Mark the symbols dependent on the input symbol as live. + void markDependentsLive(SymbolRef sym); }; class SymbolVisitor { diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp index 6d90d19f9e..b4a0d69c00 100644 --- a/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -248,9 +248,36 @@ bool SymbolManager::canSymbolicate(QualType T) { return false; } +void SymbolManager::addSymbolDependency(const SymbolRef Primary, + const SymbolRef Dependent) { + SymbolDependencies[Primary].push_back(Dependent); +} + +void SymbolManager::removeSymbolDependencies(const SymbolRef Primary) { + SymbolDependencies.erase(Primary); +} + +const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols( + const SymbolRef Primary) { + SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary); + if (I == SymbolDependencies.end()) + return 0; + return &I->second; +} + +void SymbolReaper::markDependentsLive(SymbolRef sym) { + if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) { + for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(), + E = Deps->end(); I != E; ++I) { + markLive(*I); + } + } +} + void SymbolReaper::markLive(SymbolRef sym) { TheLiving.insert(sym); TheDead.erase(sym); + markDependentsLive(sym); } void SymbolReaper::markLive(const MemRegion *region) { @@ -299,8 +326,10 @@ bool SymbolReaper::isLiveRegion(const MemRegion *MR) { } bool SymbolReaper::isLive(SymbolRef sym) { - if (TheLiving.count(sym)) + if (TheLiving.count(sym)) { + markDependentsLive(sym); return true; + } if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) { if (isLive(derived->getParentSymbol())) { |