From 58f5ec7d56b1ebf5f90ee11226ebe7663f2821ea Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 20 Oct 2009 21:39:41 +0000 Subject: [PATCH] Add destructor and cleanup code to LocationContext (fixing some leaks). Along the way, have AnalysisManager periodically cleanup its AnalysisContextManager and LocationContextManager objects, as they don't need to forever retain all the CFGs ever created when analyzing a file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84684 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/AnalysisContext.h | 8 +++++++ .../Analysis/PathSensitive/AnalysisManager.h | 5 +++++ lib/Analysis/AnalysisContext.cpp | 21 +++++++++++++++++++ lib/Frontend/AnalysisConsumer.cpp | 3 +++ 4 files changed, 37 insertions(+) diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h index ffe282d3ca..8e02ccf382 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -60,6 +60,9 @@ public: ~AnalysisContextManager(); AnalysisContext *getContext(const Decl *D); + + // Discard all previously created AnalysisContexts. + void clear(); }; class LocationContext : public llvm::FoldingSetNode { @@ -155,12 +158,17 @@ class LocationContextManager { llvm::FoldingSet Contexts; public: + ~LocationContextManager(); + StackFrameContext *getStackFrame(AnalysisContext *ctx, const LocationContext *parent, const Stmt *s); ScopeContext *getScope(AnalysisContext *ctx, const LocationContext *parent, const Stmt *s); + + /// Discard all previously created LocationContext objects. + void clear(); }; } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h index e97f80576a..1a64f56ee8 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisManager.h +++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h @@ -65,6 +65,11 @@ public: AScope(ScopeDecl), DisplayedFunction(!displayProgress), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim) {} + + void ClearContexts() { + LocCtxMgr.clear(); + AnaCtxMgr.clear(); + } StoreManagerCreator getStoreManagerCreator() { return CreateStoreMgr; diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index a4cb66be04..640912ad6b 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -33,6 +33,12 @@ AnalysisContextManager::~AnalysisContextManager() { delete I->second; } +void AnalysisContextManager::clear() { + for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) + delete I->second; + Contexts.clear(); +} + Stmt *AnalysisContext::getBody() { if (const FunctionDecl *FD = dyn_cast(D)) return FD->getBody(); @@ -103,6 +109,21 @@ void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, ID.AddPointer(s); } +LocationContextManager::~LocationContextManager() { + clear(); +} + +void LocationContextManager::clear() { + for (llvm::FoldingSet::iterator I = Contexts.begin(), + E = Contexts.end(); I != E; ) { + LocationContext *LC = &*I; + ++I; + delete LC; + } + + Contexts.clear(); +} + StackFrameContext* LocationContextManager::getStackFrame(AnalysisContext *ctx, const LocationContext *parent, diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index dbf9364f87..55f2740059 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -273,6 +273,9 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) { !Ctx->getSourceManager().isFromMainFile(D->getLocation())) return; + // Clear the AnalysisManager of old AnalysisContexts. + Mgr->ClearContexts(); + // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) (*I)(*Mgr, D); -- 2.40.0