diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index dc3d15b25979a354a18417db1aa584c49a01cf57..55ef1119e8b5db5645c52403583020d74443f729 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -91,7 +91,7 @@ public: }; typedef const SymbolData* SymbolRef; -typedef llvm::SmallVector SymbolRefSmallVectorTy; +typedef llvm::SmallVector SymbolRefSmallVectorTy; /// A symbol representing the value of a MemRegion. class SymbolRegionValue : public SymbolData { @@ -358,7 +358,7 @@ public: class SymbolManager { typedef llvm::FoldingSet DataSetTy; - typedef llvm::DenseMap SymbolDependTy; + typedef llvm::DenseMap SymbolDependTy; DataSetTy DataSet; /// Stores the extra dependencies between symbols: the data should be kept @@ -372,7 +372,8 @@ class SymbolManager { public: SymbolManager(ASTContext& ctx, BasicValueFactory &bv, llvm::BumpPtrAllocator& bpalloc) - : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} + : SymbolDependencies(16), SymbolCounter(0), + BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} ~SymbolManager(); @@ -423,9 +424,6 @@ public: /// 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; } @@ -433,10 +431,16 @@ public: }; class SymbolReaper { + enum SymbolStatus { + NotProcessed, + HaveMarkedDependents + }; + typedef llvm::DenseSet SymbolSetTy; + typedef llvm::DenseMap SymbolMapTy; typedef llvm::DenseSet RegionSetTy; - SymbolSetTy TheLiving; + SymbolMapTy TheLiving; SymbolSetTy MetadataInUse; SymbolSetTy TheDead; diff --git a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp index b4a0d69c00877057df318034c33e42169f9047f0..ba8504c27567db08f7b53e3c484bd4f600cd612d 100644 --- a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -231,7 +231,13 @@ QualType SymbolRegionValue::getType(ASTContext& C) const { return R->getValueType(); } -SymbolManager::~SymbolManager() {} +SymbolManager::~SymbolManager() { + for (SymbolDependTy::const_iterator I = SymbolDependencies.begin(), + E = SymbolDependencies.end(); I != E; ++I) { + delete I->second; + } + +} bool SymbolManager::canSymbolicate(QualType T) { T = T.getCanonicalType(); @@ -250,11 +256,15 @@ bool SymbolManager::canSymbolicate(QualType T) { void SymbolManager::addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent) { - SymbolDependencies[Primary].push_back(Dependent); -} - -void SymbolManager::removeSymbolDependencies(const SymbolRef Primary) { - SymbolDependencies.erase(Primary); + SymbolDependTy::iterator I = SymbolDependencies.find(Primary); + SymbolRefSmallVectorTy *dependencies = 0; + if (I == SymbolDependencies.end()) { + dependencies = new SymbolRefSmallVectorTy(); + SymbolDependencies[Primary] = dependencies; + } else { + dependencies = I->second; + } + dependencies->push_back(Dependent); } const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols( @@ -262,20 +272,29 @@ const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols( SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary); if (I == SymbolDependencies.end()) return 0; - return &I->second; + return I->second; } void SymbolReaper::markDependentsLive(SymbolRef sym) { + // Do not mark dependents more then once. + SymbolMapTy::iterator LI = TheLiving.find(sym); + assert(LI != TheLiving.end() && "The primary symbol is not live."); + if (LI->second == HaveMarkedDependents) + return; + LI->second = HaveMarkedDependents; + if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) { for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(), E = Deps->end(); I != E; ++I) { + if (TheLiving.find(*I) != TheLiving.end()) + continue; markLive(*I); } } } void SymbolReaper::markLive(SymbolRef sym) { - TheLiving.insert(sym); + TheLiving[sym] = NotProcessed; TheDead.erase(sym); markDependentsLive(sym); }