Make the analyzer store (memory model) a command line option.

llvm-svn: 58056
This commit is contained in:
Ted Kremenek 2008-10-24 01:04:59 +00:00
parent 607f67b16c
commit 6779f893b9
8 changed files with 63 additions and 9 deletions

View File

@ -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

View File

@ -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<PathDiagnosticClient> 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<AnalysisConsumer>
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)

View File

@ -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

View File

@ -203,13 +203,22 @@ AnalyzeAll("analyzer-opt-analyze-headers",
"functions defined in header files"));
static llvm::cl::list<Analyses>
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<AnalysisStores>
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,

View File

@ -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) {

View File

@ -88,6 +88,7 @@ public:
};
StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
StoreManager* CreateRegionStoreManager(GRStateManager& StMgr);
} // end clang namespace

View File

@ -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),

View File

@ -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);