[analyzer] Hide developer-only checker/package options by default

These options are now only visible under
-analyzer-checker-option-help-developer.

Differential Revision: https://reviews.llvm.org/D61839

llvm-svn: 361561
This commit is contained in:
Kristof Umann 2019-05-23 22:07:16 +00:00
parent d82ddfa7c3
commit 7e55ed84d0
10 changed files with 122 additions and 70 deletions

View File

@ -151,6 +151,10 @@ def analyzer_config : Separate<["-"], "analyzer-config">,
def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">,
HelpText<"Display the list of checker and package options">;
def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">,
HelpText<"Display the list of checker and package options meant for "
"development purposes only">;
def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">,
HelpText<"Don't emit errors on invalid analyzer-config inputs">;

View File

@ -25,13 +25,22 @@ class Type<CmdLineOptionTypeEnum val> {
bits<2> Type = val.Type;
}
/// Marks the entry hidden. Hidden entries won't be displayed in
/// -analyzer-checker-option-help.
class HiddenEnum<bit val> {
bit Val = val;
}
def DontHide : HiddenEnum<0>;
def Hide : HiddenEnum<1>;
/// Describes an option for a checker or a package.
class CmdLineOption<CmdLineOptionTypeEnum type, string cmdFlag, string desc,
string defaultVal> {
string defaultVal, HiddenEnum isHidden = DontHide> {
bits<2> Type = type.Type;
string CmdFlag = cmdFlag;
string Desc = desc;
string DefaultVal = defaultVal;
string CmdFlag = cmdFlag;
string Desc = desc;
string DefaultVal = defaultVal;
bit Hidden = isHidden.Val;
}
/// Describes a list of package options.

View File

@ -519,7 +519,8 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">,
"for each uninitalized field, as opposed to emitting one "
"warning per constructor call, and listing the uninitialized "
"fields that belongs to it in notes.",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"CheckPointeeInitialization",
"If set to false, the checker will not analyze "
@ -918,7 +919,8 @@ def RetainCountChecker : Checker<"RetainCount">,
"OSObject instances. By default, the checker only checks "
"retain-release rules for Objective-C NSObject instances "
"and CoreFoundation objects.",
"true">,
"true",
Hide>,
CmdLineOption<Boolean,
"TrackNSCFStartParam",
"Check not only that the code follows retain-release rules "
@ -1046,7 +1048,8 @@ def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">,
"(Aggressive) or NonLocalized only if it is not backed by a "
"SymRegion (Non-Aggressive), basically leaving only string "
"literals as NonLocalized.",
"false">
"false",
Hide>
]>,
Documentation<HasDocumentation>;
@ -1110,67 +1113,83 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">,
CmdLineOption<Boolean,
"PreStmtCastExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PostStmtCastExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PreStmtArraySubscriptExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PostStmtArraySubscriptExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PreStmtCXXNewExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PostStmtCXXNewExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PreStmtOffsetOfExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PostStmtOffsetOfExpr",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PreCall",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"PostCall",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"EndFunction",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"NewAllocator",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"Bind",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"LiveSymbols",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"RegionChanges",
"",
"false">,
"false",
Hide>,
CmdLineOption<Boolean,
"*",
"Enables all callbacks.",
"false">
"false",
Hide>
]>,
Documentation<NotDocumented>;

View File

@ -224,6 +224,7 @@ public:
unsigned ShowCheckerHelpDeveloper : 1;
unsigned ShowEnabledCheckerList : 1;
unsigned ShowCheckerOptionList : 1;
unsigned ShowCheckerOptionDeveloperList : 1;
unsigned ShowConfigOptionsList : 1;
unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
unsigned AnalyzeAll : 1;
@ -287,7 +288,8 @@ public:
AnalyzerOptions()
: DisableAllChecks(false), ShowCheckerHelp(false),
ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
ShowEnabledCheckerList(false), ShowCheckerOptionList(false),
ShowEnabledCheckerList(false),
ShowCheckerOptionList(false), ShowCheckerOptionDeveloperList(false),
ShowConfigOptionsList(false), AnalyzeAll(false),
AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),

View File

@ -98,11 +98,13 @@ public:
StringRef OptionName;
StringRef DefaultValStr;
StringRef Description;
bool IsHidden;
CmdLineOption(StringRef OptionType, StringRef OptionName,
StringRef DefaultValStr, StringRef Description)
StringRef DefaultValStr, StringRef Description, bool IsHidden)
: OptionType(OptionType), OptionName(OptionName),
DefaultValStr(DefaultValStr), Description(Description) {
DefaultValStr(DefaultValStr), Description(Description),
IsHidden(IsHidden) {
assert((OptionType == "bool" || OptionType == "string" ||
OptionType == "int") &&
@ -239,7 +241,7 @@ public:
/// non-compatibility mode.
void addCheckerOption(StringRef OptionType, StringRef CheckerFullName,
StringRef OptionName, StringRef DefaultValStr,
StringRef Description);
StringRef Description, bool IsHidden = false);
/// Adds a package to the registry.
void addPackage(StringRef FullName);
@ -255,7 +257,7 @@ public:
/// non-compatibility mode.
void addPackageOption(StringRef OptionType, StringRef PackageFullName,
StringRef OptionName, StringRef DefaultValStr,
StringRef Description);
StringRef Description, bool IsHidden = false);
// FIXME: This *really* should be added to the frontend flag descriptions.
/// Initializes a CheckerManager by calling the initialization functions for

View File

@ -289,6 +289,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
Opts.ShowCheckerHelpDeveloper =
Args.hasArg(OPT_analyzer_checker_help_developer);
Opts.ShowCheckerOptionList = Args.hasArg(OPT_analyzer_checker_option_help);
Opts.ShowCheckerOptionDeveloperList =
Args.hasArg(OPT_analyzer_checker_option_help_developer);
Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help);
Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers);
Opts.ShouldEmitErrorsOnInvalidConfigValue =

View File

@ -249,7 +249,7 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
}
// Honor -analyzer-checker-option-help.
if (Clang->getAnalyzerOpts()->ShowCheckerOptionList) {
if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionDeveloperList) {
ento::printCheckerConfigList(llvm::outs(),
Clang->getFrontendOpts().Plugins,
*Clang->getAnalyzerOpts(),

View File

@ -180,12 +180,12 @@ CheckerRegistry::CheckerRegistry(
addDependency(FULLNAME, DEPENDENCY);
#define GET_CHECKER_OPTIONS
#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \
addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC);
#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \
addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN);
#define GET_PACKAGE_OPTIONS
#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \
addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC);
#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \
addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN);
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER_DEPENDENCY
@ -396,10 +396,10 @@ void CheckerRegistry::addPackageOption(StringRef OptionType,
StringRef PackageFullName,
StringRef OptionName,
StringRef DefaultValStr,
StringRef Description) {
StringRef Description, bool IsHidden) {
PackageOptions.emplace_back(
PackageFullName,
CmdLineOption{OptionType, OptionName, DefaultValStr, Description});
PackageFullName, CmdLineOption{OptionType, OptionName, DefaultValStr,
Description, IsHidden});
}
void CheckerRegistry::addChecker(InitializationFunction Rfn,
@ -421,10 +421,10 @@ void CheckerRegistry::addCheckerOption(StringRef OptionType,
StringRef CheckerFullName,
StringRef OptionName,
StringRef DefaultValStr,
StringRef Description) {
StringRef Description, bool IsHidden) {
CheckerOptions.emplace_back(
CheckerFullName,
CmdLineOption{OptionType, OptionName, DefaultValStr, Description});
CheckerFullName, CmdLineOption{OptionType, OptionName, DefaultValStr,
Description, IsHidden});
}
void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {
@ -577,6 +577,9 @@ void CheckerRegistry::printCheckerOptionList(raw_ostream &Out) const {
}
for (const std::pair<StringRef, const CmdLineOption &> &Entry : OptionMap) {
if (!AnOpts.ShowCheckerOptionDeveloperList && Entry.second.IsHidden)
continue;
const CmdLineOption &Option = Entry.second;
std::string FullOption = (Entry.first + ":" + Option.OptionName).str();

View File

@ -1,5 +1,8 @@
// RUN: %clang_cc1 -analyzer-checker-option-help 2>&1 | FileCheck %s
// RUN: %clang_cc1 -analyzer-checker-option-help-developer \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-HIDDEN
// CHECK: OVERVIEW: Clang Static Analyzer Checker and Package Option List
//
// CHECK: USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
@ -17,3 +20,6 @@
// CHECK: the first statement in the group is representative
// CHECK: for all other statements in the group in
// CHECK: terms of complexity. (default: 50)
// CHECK-NOT: optin.cplusplus.UninitializedObject:NotesAsWarnings
// CHECK-HIDDEN: optin.cplusplus.UninitializedObject:NotesAsWarnings

View File

@ -113,6 +113,7 @@ static std::string getCheckerOptionType(const Record &R) {
static bool isHidden(const Record *R) {
if (R->getValueAsBit("Hidden"))
return true;
// Not declared as hidden, check the parent package if it is hidden.
if (DefInit *DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage")))
return isHidden(DI->getDef());
@ -121,21 +122,38 @@ static bool isHidden(const Record *R) {
}
static void printChecker(llvm::raw_ostream &OS, const Record &R) {
OS << "CHECKER(" << "\"";
OS.write_escaped(getCheckerFullName(&R)) << "\", ";
OS << R.getName() << ", ";
OS << "\"";
OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
OS << "\"";
OS.write_escaped(getCheckerDocs(R));
OS << "\", ";
OS << "CHECKER(" << "\"";
OS.write_escaped(getCheckerFullName(&R)) << "\", ";
OS << R.getName() << ", ";
OS << "\"";
OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
OS << "\"";
OS.write_escaped(getCheckerDocs(R));
OS << "\", ";
if (!isHidden(&R))
OS << "false";
else
OS << "true";
if (!isHidden(&R))
OS << "false";
else
OS << "true";
OS << ")\n";
OS << ")\n";
}
static void printOption(llvm::raw_ostream &OS, StringRef FullName,
const Record &R) {
OS << "\"";
OS.write_escaped(getCheckerOptionType(R)) << "\", \"";
OS.write_escaped(FullName) << "\", ";
OS << '\"' << getStringValue(R, "CmdFlag") << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(R, "Desc")) << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(R, "DefaultVal")) << "\", ";
if (!R.getValueAsBit("Hidden"))
OS << "false";
else
OS << "true";
}
namespace clang {
@ -196,14 +214,8 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record *> PackageOptions = Package
->getValueAsListOfDefs("PackageOptions");
for (Record *PackageOpt : PackageOptions) {
OS << "PACKAGE_OPTION(\"";
OS.write_escaped(getCheckerOptionType(*PackageOpt)) << "\", \"";
OS.write_escaped(getPackageFullName(Package)) << "\", ";
OS << '\"' << getStringValue(*PackageOpt, "CmdFlag") << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(*PackageOpt, "Desc")) << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(*PackageOpt, "DefaultVal")) << "\"";
OS << "PACKAGE_OPTION(";
printOption(OS, getPackageFullName(Package), *PackageOpt);
OS << ")\n";
}
}
@ -277,16 +289,9 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record *> CheckerOptions = Checker
->getValueAsListOfDefs("CheckerOptions");
for (Record *CheckerOpt : CheckerOptions) {
OS << "CHECKER_OPTION(\"";
OS << getCheckerOptionType(*CheckerOpt) << "\", \"";
OS.write_escaped(getCheckerFullName(Checker)) << "\", ";
OS << '\"' << getStringValue(*CheckerOpt, "CmdFlag") << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(*CheckerOpt, "Desc")) << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(*CheckerOpt, "DefaultVal")) << "\"";
OS << ")";
OS << '\n';
OS << "CHECKER_OPTION(";
printOption(OS, getCheckerFullName(Checker), *CheckerOpt);
OS << ")\n";
}
}
OS << "#endif // GET_CHECKER_OPTIONS\n"