From: George Karpenkov Date: Mon, 23 Oct 2017 23:59:52 +0000 (+0000) Subject: [Analyzer] Do not use static storage to for implementations created in BodyFarm.cpp X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b1d1f02e9ceb837f16cf85447f8211f331954b1;p=clang [Analyzer] Do not use static storage to for implementations created in BodyFarm.cpp Differential Revision: https://reviews.llvm.org/D39208 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316400 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h index ebec0d26ba..1486071891 100644 --- a/include/clang/Analysis/AnalysisDeclContext.h +++ b/include/clang/Analysis/AnalysisDeclContext.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H #include "clang/AST/Decl.h" +#include "clang/Analysis/BodyFarm.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CodeInjector.h" #include "llvm/ADT/DenseMap.h" @@ -409,6 +410,7 @@ class AnalysisDeclContextManager { typedef llvm::DenseMap> ContextMap; + ASTContext &ASTCtx; ContextMap Contexts; LocationContextManager LocContexts; CFG::BuildOptions cfgBuildOptions; @@ -416,22 +418,25 @@ class AnalysisDeclContextManager { /// Pointer to an interface that can provide function bodies for /// declarations from external source. std::unique_ptr Injector; - + + /// Pointer to a factory for creating and caching implementations for common + /// methods during the analysis. + BodyFarm *BdyFrm = nullptr; + /// Flag to indicate whether or not bodies should be synthesized /// for well-known functions. bool SynthesizeBodies; public: - AnalysisDeclContextManager(bool useUnoptimizedCFG = false, + AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false, bool addImplicitDtors = false, bool addInitializers = false, bool addTemporaryDtors = false, - bool addLifetime = false, - bool addLoopExit = false, + bool addLifetime = false, bool addLoopExit = false, bool synthesizeBodies = false, bool addStaticInitBranches = false, bool addCXXNewAllocator = true, - CodeInjector* injector = nullptr); + CodeInjector *injector = nullptr); ~AnalysisDeclContextManager(); @@ -472,6 +477,9 @@ public: return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx); } + /// Get and lazily create a {@code BodyFarm} instance. + BodyFarm *getBodyFarm(); + /// Discard all previously created AnalysisDeclContexts. void clear(); diff --git a/lib/Analysis/BodyFarm.h b/include/clang/Analysis/BodyFarm.h similarity index 93% rename from lib/Analysis/BodyFarm.h rename to include/clang/Analysis/BodyFarm.h index edbe996246..14cf2624b8 100644 --- a/lib/Analysis/BodyFarm.h +++ b/include/clang/Analysis/BodyFarm.h @@ -28,11 +28,11 @@ class ObjCMethodDecl; class ObjCPropertyDecl; class Stmt; class CodeInjector; - + class BodyFarm { public: BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {} - + /// Factory method for creating bodies for ordinary functions. Stmt *getBody(const FunctionDecl *D); @@ -40,12 +40,12 @@ public: Stmt *getBody(const ObjCMethodDecl *D); private: - typedef llvm::DenseMap > BodyMap; + typedef llvm::DenseMap> BodyMap; ASTContext &C; BodyMap Bodies; CodeInjector *Injector; }; -} +} // namespace clang #endif diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp index 73eb142f97..2171194edc 100644 --- a/lib/Analysis/AnalysisDeclContext.cpp +++ b/lib/Analysis/AnalysisDeclContext.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/AnalysisDeclContext.h" -#include "BodyFarm.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -23,6 +22,7 @@ #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" +#include "clang/Analysis/BodyFarm.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CFGStmtMap.h" #include "clang/Analysis/Support/BumpVector.h" @@ -63,18 +63,12 @@ AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr, cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; } -AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG, - bool addImplicitDtors, - bool addInitializers, - bool addTemporaryDtors, - bool addLifetime, - bool addLoopExit, - bool synthesizeBodies, - bool addStaticInitBranch, - bool addCXXNewAllocator, - CodeInjector *injector) - : Injector(injector), SynthesizeBodies(synthesizeBodies) -{ +AnalysisDeclContextManager::AnalysisDeclContextManager( + ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors, + bool addInitializers, bool addTemporaryDtors, bool addLifetime, + bool addLoopExit, bool synthesizeBodies, bool addStaticInitBranch, + bool addCXXNewAllocator, CodeInjector *injector) + : ASTCtx(ASTCtx), Injector(injector), SynthesizeBodies(synthesizeBodies) { cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG; cfgBuildOptions.AddImplicitDtors = addImplicitDtors; cfgBuildOptions.AddInitializers = addInitializers; @@ -87,11 +81,6 @@ AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG, void AnalysisDeclContextManager::clear() { Contexts.clear(); } -static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) { - static BodyFarm *BF = new BodyFarm(C, injector); - return *BF; -} - Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { IsAutosynthesized = false; if (const FunctionDecl *FD = dyn_cast(D)) { @@ -99,8 +88,7 @@ Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { if (auto *CoroBody = dyn_cast_or_null(Body)) Body = CoroBody->getBody(); if (Manager && Manager->synthesizeBodies()) { - Stmt *SynthesizedBody = - getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD); + Stmt *SynthesizedBody = Manager->getBodyFarm()->getBody(FD); if (SynthesizedBody) { Body = SynthesizedBody; IsAutosynthesized = true; @@ -111,8 +99,7 @@ Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { else if (const ObjCMethodDecl *MD = dyn_cast(D)) { Stmt *Body = MD->getBody(); if (Manager && Manager->synthesizeBodies()) { - Stmt *SynthesizedBody = - getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD); + Stmt *SynthesizedBody = Manager->getBodyFarm()->getBody(MD); if (SynthesizedBody) { Body = SynthesizedBody; IsAutosynthesized = true; @@ -317,6 +304,12 @@ AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) { return AC.get(); } +BodyFarm *AnalysisDeclContextManager::getBodyFarm() { + if (!BdyFrm) + BdyFrm = new BodyFarm(ASTCtx, Injector.get()); + return BdyFrm; +} + const StackFrameContext * AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned Idx) { @@ -610,7 +603,10 @@ AnalysisDeclContext::~AnalysisDeclContext() { } } -AnalysisDeclContextManager::~AnalysisDeclContextManager() {} +AnalysisDeclContextManager::~AnalysisDeclContextManager() { + if (!BdyFrm) + delete BdyFrm; +} LocationContext::~LocationContext() {} diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp index 6a8b529bba..dd348847b3 100644 --- a/lib/Analysis/BodyFarm.cpp +++ b/lib/Analysis/BodyFarm.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "BodyFarm.h" +#include "clang/Analysis/BodyFarm.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp index b7e2c277ef..1cc08f0d9f 100644 --- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -14,33 +14,25 @@ using namespace ento; void AnalysisManager::anchor() { } -AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, - const LangOptions &lang, - const PathDiagnosticConsumers &PDC, - StoreManagerCreator storemgr, - ConstraintManagerCreator constraintmgr, - CheckerManager *checkerMgr, - AnalyzerOptions &Options, - CodeInjector *injector) - : AnaCtxMgr(Options.UnoptimizedCFG, - Options.includeImplicitDtorsInCFG(), - /*AddInitializers=*/true, - Options.includeTemporaryDtorsInCFG(), - Options.includeLifetimeInCFG(), - // Adding LoopExit elements to the CFG is a requirement for loop - // unrolling. - Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(), - Options.shouldSynthesizeBodies(), - Options.shouldConditionalizeStaticInitializers(), - /*addCXXNewAllocator=*/true, - injector), - Ctx(ctx), - Diags(diags), - LangOpts(lang), - PathConsumers(PDC), - CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - CheckerMgr(checkerMgr), - options(Options) { +AnalysisManager::AnalysisManager( + ASTContext &ASTCtx, DiagnosticsEngine &diags, const LangOptions &lang, + const PathDiagnosticConsumers &PDC, StoreManagerCreator storemgr, + ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, + AnalyzerOptions &Options, CodeInjector *injector) + : AnaCtxMgr(ASTCtx, Options.UnoptimizedCFG, + Options.includeImplicitDtorsInCFG(), + /*AddInitializers=*/true, Options.includeTemporaryDtorsInCFG(), + Options.includeLifetimeInCFG(), + // Adding LoopExit elements to the CFG is a requirement for loop + // unrolling. + Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(), + Options.shouldSynthesizeBodies(), + Options.shouldConditionalizeStaticInitializers(), + /*addCXXNewAllocator=*/true, + injector), + Ctx(ASTCtx), Diags(diags), LangOpts(lang), PathConsumers(PDC), + CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), + CheckerMgr(checkerMgr), options(Options) { AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd(); }