diff options
-rw-r--r-- | include/clang/Basic/DiagnosticDriverKinds.td | 6 | ||||
-rw-r--r-- | include/clang/Driver/CC1Options.td | 5 | ||||
-rw-r--r-- | include/clang/Frontend/AnalyzerOptions.h | 2 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h | 6 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h | 4 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 30 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/AnalysisManager.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 13 |
8 files changed, 65 insertions, 7 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index bc961ee557..724a9a813b 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -141,5 +141,9 @@ def warn_drv_pch_not_first_include : Warning< def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; - + +def err_analyzer_config_no_value : Error< + "analyzer-config option '%0' has a key but no value">; +def err_analyzer_config_multiple_values : Error< + "analyzer-config option '%0' should contain only one ':'">; } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 86b9bdec6c..9213d217ef 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -119,6 +119,11 @@ def analyzer_disable_checker_EQ : Joined<"-analyzer-disable-checker=">, def analyzer_checker_help : Flag<"-analyzer-checker-help">, HelpText<"Display the list of analyzer checkers that are available">; +def analyzer_config : Separate<"-analyzer-config">, + HelpText<"Choose analyzer checkers to enable">; +def analyzer_config_EQ : Joined<"-analyzer-config=">, + Alias<analyzer_config>; + //===----------------------------------------------------------------------===// // Migrator Options //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/AnalyzerOptions.h b/include/clang/Frontend/AnalyzerOptions.h index 4e5d7cba7c..5c508ecb2a 100644 --- a/include/clang/Frontend/AnalyzerOptions.h +++ b/include/clang/Frontend/AnalyzerOptions.h @@ -17,6 +17,7 @@ #include <string> #include <vector> +#include "llvm/ADT/StringMap.h" namespace clang { class ASTConsumer; @@ -78,6 +79,7 @@ class AnalyzerOptions { public: /// \brief Pair of checker name and enable/disable. std::vector<std::pair<std::string, bool> > CheckersControlList; + llvm::StringMap<std::string> Config; AnalysisStores AnalysisStoreOpt; AnalysisConstraints AnalysisConstraintsOpt; AnalysisDiagClients AnalysisDiagOpt; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 876196ba4f..24218be99d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -81,6 +81,11 @@ public: /// strategy. We get better code coverage when retry is enabled. bool NoRetryExhausted; + typedef llvm::StringMap<std::string> ConfigTable; + + /// \brief A key-value table of use-specified configuration values. + const ConfigTable &Config; + public: AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags, const LangOptions &lang, @@ -88,6 +93,7 @@ public: StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, + const ConfigTable &Config, unsigned maxnodes, unsigned maxvisit, bool vizdot, bool vizubi, AnalysisPurgeMode purge, bool eager, bool trim, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 478bf71d8d..c260c1b363 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -64,6 +64,10 @@ public: return Eng.getStoreManager(); } + const AnalysisManager::ConfigTable &getConfig() const { + return Eng.getAnalysisManager().Config; + } + /// \brief Returns the previous node in the exploded graph, which includes /// the state of the program before the checker ran. Note, checkers should /// not retain the node in their state since the nodes might get invalidated. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 4f166b0e91..8935e775a7 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1154,6 +1154,36 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, for (unsigned i = 0, e = checkers.size(); i != e; ++i) Opts.CheckersControlList.push_back(std::make_pair(checkers[i], enable)); } + + // Go through the analyzer configuration options. + for (arg_iterator it = Args.filtered_begin(OPT_analyzer_config), + ie = Args.filtered_end(); it != ie; ++it) { + const Arg *A = *it; + A->claim(); + // We can have a list of comma separated config names, e.g: + // '-analyzer-config=key1:val1,key2:val2' + StringRef configList = A->getValue(Args); + SmallVector<StringRef, 4> configVals; + configList.split(configVals, ","); + for (unsigned i = 0, e = configVals.size(); i != e; ++i) { + StringRef key, val; + llvm::tie(key, val) = configVals[i].split(":"); + if (val.empty()) { + Diags.Report(SourceLocation(), + diag::err_analyzer_config_no_value) << configVals[i]; + Success = false; + break; + } + if (val.find(':') != StringRef::npos) { + Diags.Report(SourceLocation(), + diag::err_analyzer_config_multiple_values) + << configVals[i]; + Success = false; + break; + } + Opts.Config[key] = val; + } + } return Success; } diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp index efeba17a62..339208b374 100644 --- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -20,6 +20,7 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, + const ConfigTable &Config, unsigned maxnodes, unsigned maxvisit, bool vizdot, bool vizubi, AnalysisPurgeMode purge, @@ -36,7 +37,7 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, Ctx(ctx), Diags(diags), LangOpts(lang), PathConsumers(PDC), CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - CheckerMgr(checkerMgr), + CheckerMgr(checkerMgr), MaxNodes(maxnodes), MaxVisit(maxvisit), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim), @@ -45,7 +46,8 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, InlineMaxStackDepth(inlineMaxStack), InlineMaxFunctionSize(inlineMaxFunctionSize), InliningMode(IMode), - NoRetryExhausted(NoRetry) + NoRetryExhausted(NoRetry), + Config(Config) { AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd(); } diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 34b5266e4b..b81ee7fc59 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -255,11 +255,16 @@ public: CreateStoreMgr, CreateConstraintMgr, checkerMgr.get(), - Opts.MaxNodes, Opts.MaxLoop, - Opts.VisualizeEGDot, Opts.VisualizeEGUbi, - Opts.AnalysisPurgeOpt, Opts.EagerlyAssume, + Opts.Config, + Opts.MaxNodes, + Opts.MaxLoop, + Opts.VisualizeEGDot, + Opts.VisualizeEGUbi, + Opts.AnalysisPurgeOpt, + Opts.EagerlyAssume, Opts.TrimGraph, - Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors, + Opts.UnoptimizedCFG, + Opts.CFGAddImplicitDtors, Opts.EagerlyTrimEGraph, Opts.IPAMode, Opts.InlineMaxStackDepth, |