Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -291,6 +291,9 @@ "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 '='">; +def warn_analyzer_config_unknown_config : Warning< + "unkown -analyzer-config option '%0'">, + InGroup; def err_drv_invalid_hvx_length : Error< "-mhvx-length is not supported without a -mhvx/-mhvx= flag">; Index: include/clang/StaticAnalyzer/Core/AnalyzerOptions.h =================================================================== --- include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -320,6 +320,15 @@ template T getDefaultValForUserMode(T ShallowVal, T DeepVal); + std::vector getConfigOptionList() const { + return { +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ + CMDFLAG, +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" +#undef ANALYZER_OPTION + }; + } + #define ANALYZER_OPTION_WITH_FN(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL, \ CREATE_FN) \ TYPE CREATE_FN(); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -314,6 +314,8 @@ Opts.CheckersControlList.emplace_back(checker, enable); } + std::vector RegisteredOptions = Opts.getConfigOptionList(); + // Go through the analyzer configuration options. for (const auto *A : Args.filtered(OPT_analyzer_config)) { A->claim(); @@ -338,6 +340,13 @@ Success = false; break; } + // Check whether this really is a valid -analyzer-condfig option. + // TODO: We should check whether all options are valid or not, but for + // now, skip checker options. + if (key.count(':') == 0) { + if (llvm::find(RegisteredOptions, key) == RegisteredOptions.end()) + Diags.Report(diag::warn_analyzer_config_unknown_config) << key; + } Opts.Config[key] = val; } }