From: Ted Kremenek Date: Fri, 24 Oct 2008 01:04:59 +0000 (+0000) Subject: Make the analyzer store (memory model) a command line option. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=95c7b00fe857a61a19185483aa0d85492ec9e258;p=clang Make the analyzer store (memory model) a command line option. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58056 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/Analyses.def b/Driver/Analyses.def index 841f0c1da1..0661a4e946 100644 --- a/Driver/Analyses.def +++ b/Driver/Analyses.def @@ -11,6 +11,14 @@ // //===----------------------------------------------------------------------===// +#ifndef ANALYSIS +#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) +#endif + +#ifndef ANALYSIS_STORE +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC) +#endif + ANALYSIS(CFGDump, "cfg-dump", "Display Control-Flow Graphs", Code) @@ -43,4 +51,9 @@ ANALYSIS(CheckerSimple, "checker-simple", ANALYSIS(CheckerCFRef, "checker-cfref", "Run the [Core] Foundation reference count checker", Code) + +ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store") +ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store") + #undef ANALYSIS +#undef ANALYSIS_STORE diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp index e22178b73e..12ba732bd9 100644 --- a/Driver/AnalysisConsumer.cpp +++ b/Driver/AnalysisConsumer.cpp @@ -65,7 +65,7 @@ namespace { const bool VisGraphviz; const bool VisUbigraph; const bool TrimGraph; - const LangOptions& LOpts; + const LangOptions& LOpts; Diagnostic &Diags; ASTContext* Ctx; Preprocessor* PP; @@ -74,19 +74,21 @@ namespace { const std::string FName; llvm::OwningPtr PD; bool AnalyzeAll; + AnalysisStores SM; AnalysisConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, const std::string& fname, const std::string& htmldir, + AnalysisStores sm, bool visgraphviz, bool visubi, bool trim, bool analyzeAll) : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim), LOpts(lopts), Diags(diags), Ctx(0), PP(pp), PPF(ppf), HTMLDir(htmldir), FName(fname), - AnalyzeAll(analyzeAll) {} + AnalyzeAll(analyzeAll), SM(sm) {} void addCodeAction(CodeAction action) { FunctionActions.push_back(action); @@ -126,6 +128,15 @@ namespace { Decl* getCodeDecl() const { return D; } Stmt* getBody() const { return Body; } + GRStateManager::StoreManagerCreator getStoreManagerCreator() { + switch (C.SM) { + default: +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)\ +case NAME##Model: return Create##NAME##Manager; +#include "Analyses.def" + } + }; + virtual CFG* getCFG() { if (!cfg) cfg.reset(CFG::buildCFG(getBody())); return cfg.get(); @@ -324,7 +335,9 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, // Display progress. mgr.DisplayFunction(); - GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L); + GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L, + mgr.getStoreManagerCreator()); + Eng.setTransferFunctions(tf); if (StandardWarnings) { @@ -436,6 +449,7 @@ static void ActionWarnObjCMethSigs(AnalysisManager& mgr) { //===----------------------------------------------------------------------===// ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End, + AnalysisStores SM, Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, @@ -446,7 +460,7 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End, bool analyzeAll) { llvm::OwningPtr - C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, + C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM, VisGraphviz, VisUbi, trim, analyzeAll)); for ( ; Beg != End ; ++Beg) diff --git a/Driver/AnalysisConsumer.h b/Driver/AnalysisConsumer.h index daec6f3441..420714fd60 100644 --- a/Driver/AnalysisConsumer.h +++ b/Driver/AnalysisConsumer.h @@ -21,8 +21,15 @@ enum Analyses { #include "Analyses.def" NumAnalyses }; + +enum AnalysisStores { +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC) NAME##Model, +#include "Analyses.def" +NumStores +}; ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End, + AnalysisStores SM, Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, @@ -30,7 +37,7 @@ ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End, const std::string& htmldir, bool VisualizeGraphViz, bool VisualizeUbi, - bool VizTrimGraph, + bool VizTrimGraph, bool AnalyzeAll); } // end clang namespace diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 47d422dcbc..e6c696225d 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -203,13 +203,22 @@ AnalyzeAll("analyzer-opt-analyze-headers", "functions defined in header files")); static llvm::cl::list -AnalysisList(llvm::cl::desc("Available Source Code Analyses:"), +AnalysisList(llvm::cl::desc("SCA Checks/Analyses:"), llvm::cl::values( #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ clEnumValN(NAME, CMDFLAG, DESC), #include "Analyses.def" clEnumValEnd)); +static llvm::cl::opt +AnalysisStoreOpt(llvm::cl::desc("SCA Low-Level Options (Store):"), + llvm::cl::init(BasicStoreModel), + llvm::cl::values( +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)\ +clEnumValN(NAME##Model, "analyzer-store-" CMDFLAG, DESC), +#include "Analyses.def" +clEnumValEnd)); + //===----------------------------------------------------------------------===// // Language Options //===----------------------------------------------------------------------===// @@ -1190,6 +1199,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, assert (!AnalysisList.empty()); return CreateAnalysisConsumer(&AnalysisList[0], &AnalysisList[0]+AnalysisList.size(), + AnalysisStoreOpt, Diag, PP, PPF, LangOpts, AnalyzeSpecificFunction, OutputFile, VisualizeEGDot, VisualizeEGUbi, diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 4483eec6e6..8c5e6ed403 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -167,7 +167,10 @@ protected: UndefArgsTy MsgExprUndefArgs; public: - GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L); + GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L, + GRStateManager::StoreManagerCreator SMC = + CreateBasicStoreManager); + ~GRExprEngine(); void ExecuteWorkList(unsigned Steps = 150000) { diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index f4f0415863..5e3fa8df69 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -88,6 +88,7 @@ public: }; StoreManager* CreateBasicStoreManager(GRStateManager& StMgr); +StoreManager* CreateRegionStoreManager(GRStateManager& StMgr); } // end clang namespace diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index cbda7be2ca..1840482a3f 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -115,12 +115,13 @@ static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) { GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, - LiveVariables& L) + LiveVariables& L, + GRStateManager::StoreManagerCreator SMC) : CoreEngine(cfg, CD, Ctx, *this), G(CoreEngine.getGraph()), Liveness(L), Builder(NULL), - StateMgr(G.getContext(), CreateBasicStoreManager, + StateMgr(G.getContext(), SMC, CreateBasicConstraintManager, G.getAllocator(), G.getCFG(), L), SymMgr(StateMgr.getSymbolManager()), CurrentStmt(NULL), diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 9183fd782f..1bd29add30 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -66,6 +66,11 @@ public: } // end anonymous namespace +StoreManager* clang::CreateRegionStoreManager(GRStateManager& StMgr) { + // return new RegionStoreManager(StMgr); + return 0; // Uncomment the above line when RegionStoreManager is not abstract. +} + Loc RegionStoreManager::getElementLoc(const VarDecl* VD, SVal Idx) { MemRegion* R = MRMgr.getVarRegion(VD); ElementRegion* ER = MRMgr.getElementRegion(Idx, R);