From: Kristof Umann Date: Thu, 23 May 2019 22:52:09 +0000 (+0000) Subject: [analyzer] List checker/plugin options in 3 categories: released, alpha, developer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b240f939feefd3897b1f93c2919717f4f9a6a25;p=clang [analyzer] List checker/plugin options in 3 categories: released, alpha, developer Same patch as D62093, but for checker/plugin options, the only difference being that options for alpha checkers are implicitly marked as alpha. Differential Revision: https://reviews.llvm.org/D62093 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361566 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 6ebd679ec3..d2d471089e 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -151,6 +151,11 @@ 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_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">, + HelpText<"Display the list of in development checker and package options. " + "These are NOT considered safe, they are unstable and will emit " + "incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">; + 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">; diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td index 9fb3184cfe..6625d79559 100644 --- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -21,10 +21,21 @@ def Integer : CmdLineOptionTypeEnum<0>; def String : CmdLineOptionTypeEnum<1>; def Boolean : CmdLineOptionTypeEnum<2>; -class Type { - bits<2> Type = val.Type; +/// Describes the state of the entry. We wouldn't like to display, for example, +/// developer only entries for a list meant for end users. +class DevelopmentStageEnum val> { + bits<1> Val = val; } +/// Alpha entries are under development, might be incomplet, inkorrekt and +/// unstable. +def InAlpha : DevelopmentStageEnum<0>; + +/// Released entries are stable, produce minimal, if any false positives, +/// and emits reports that explain the occurance of the bug understandably and +/// thoroughly. +def Released : DevelopmentStageEnum<1>; + /// Marks the entry hidden. Hidden entries won't be displayed in /// -analyzer-checker-option-help. class HiddenEnum { @@ -35,11 +46,13 @@ def Hide : HiddenEnum<1>; /// Describes an option for a checker or a package. class CmdLineOption { + string defaultVal, DevelopmentStageEnum stage, + HiddenEnum isHidden = DontHide> { bits<2> Type = type.Type; string CmdFlag = cmdFlag; string Desc = desc; string DefaultVal = defaultVal; + bits<1> DevelopmentStage = stage.Val; bit Hidden = isHidden.Val; } diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td index 7669d22310..35beb51f0c 100644 --- a/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -51,7 +51,8 @@ def Nullability : Package<"nullability">, "concerned with your custom nullability annotations more " "than with following nullability specifications of system " "header functions.", - "false"> + "false", + Released> ]>; def Cplusplus : Package<"cplusplus">; @@ -391,7 +392,8 @@ def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">, "If set to true, the checker assumes that all the " "allocating and deallocating functions are annotated with " "ownership_holds, ownership_takes and ownership_returns.", - "false"> + "false", + InAlpha> ]>, Dependencies<[CStringModeling]>, Documentation, @@ -496,7 +498,8 @@ def MoveChecker: Checker<"Move">, "user has intentionally asked us to completely eliminate " "use-after-move in his code. Values: \"KnownsOnly\", " "\"KnownsAndLocals\", \"All\".", - "KnownsAndLocals"> + "KnownsAndLocals", + Released> ]>, Documentation; @@ -512,7 +515,8 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">, "If set to false, the checker won't emit warnings " "for objects that don't have at least one initialized " "field.", - "false">, + "false", + Released>, CmdLineOption, "warning per constructor call, and listing the uninitialized " "fields that belongs to it in notes.", "false", + Released, Hide>, CmdLineOption, + "false", + InAlpha>, CmdLineOption, + "\"\"", + Released>, CmdLineOption + "false", + InAlpha> ]>, Documentation; @@ -548,7 +556,8 @@ def VirtualCallChecker : Checker<"VirtualCall">, CmdLineOption + "false", + Released> ]>, Documentation; @@ -651,7 +660,8 @@ def PaddingChecker : Checker<"Padding">, "AllowedPad", "Reports are only generated if the excessive padding exceeds " "'AllowedPad' in bytes.", - "24"> + "24", + Released> ]>, Documentation; @@ -768,11 +778,13 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">, CmdLineOption, + "0x04", + Released>, CmdLineOption + "0x01", + Released> ]>, Documentation; @@ -819,7 +831,8 @@ def NumberObjectConversionChecker : Checker<"NumberObjectConversion">, "Enables detection of more conversion patterns (which are " "most likely more harmless, and therefore are more likely to " "produce false positives).", - "false"> + "false", + Released> ]>, Documentation; @@ -920,6 +933,7 @@ def RetainCountChecker : Checker<"RetainCount">, "retain-release rules for Objective-C NSObject instances " "and CoreFoundation objects.", "true", + InAlpha, Hide>, CmdLineOption, "elsewhere, but also that it fulfills its own retain count " "specification with respect to objects that it receives as " "arguments.", - "false"> + "false", + Released> ]>, Dependencies<[RetainCountBase]>, Documentation; @@ -1049,6 +1064,7 @@ def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">, "SymRegion (Non-Aggressive), basically leaving only string " "literals as NonLocalized.", "false", + InAlpha, Hide> ]>, Documentation; @@ -1114,81 +1130,97 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">, "PreStmtCastExpr", "", "false", + Released, Hide>, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption, CmdLineOption ]>, Documentation; @@ -1272,16 +1304,19 @@ def CloneChecker : Checker<"CloneChecker">, "of a statement. This constraint assumes the first statement " "in the group is representative for all other statements in " "the group in terms of complexity.", - "50">, + "50", + Released>, CmdLineOption, + "true", + Released>, CmdLineOption + "\"\"", + Released> ]>, Documentation; diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index c83696d70b..4d81f90961 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -222,9 +222,12 @@ public: unsigned ShowCheckerHelp : 1; unsigned ShowCheckerHelpAlpha : 1; unsigned ShowCheckerHelpDeveloper : 1; - unsigned ShowEnabledCheckerList : 1; + unsigned ShowCheckerOptionList : 1; + unsigned ShowCheckerOptionAlphaList : 1; unsigned ShowCheckerOptionDeveloperList : 1; + + unsigned ShowEnabledCheckerList : 1; unsigned ShowConfigOptionsList : 1; unsigned ShouldEmitErrorsOnInvalidConfigValue : 1; unsigned AnalyzeAll : 1; @@ -288,8 +291,8 @@ public: AnalyzerOptions() : DisableAllChecks(false), ShowCheckerHelp(false), ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false), - ShowEnabledCheckerList(false), - ShowCheckerOptionList(false), ShowCheckerOptionDeveloperList(false), + ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false), + ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false), ShowConfigOptionsList(false), AnalyzeAll(false), AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false), TrimGraph(false), diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 9af8f91e70..bc258160ad 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -98,13 +98,15 @@ public: StringRef OptionName; StringRef DefaultValStr; StringRef Description; + StringRef DevelopmentStatus; bool IsHidden; CmdLineOption(StringRef OptionType, StringRef OptionName, - StringRef DefaultValStr, StringRef Description, bool IsHidden) + StringRef DefaultValStr, StringRef Description, + StringRef DevelopmentStatus, bool IsHidden) : OptionType(OptionType), OptionName(OptionName), DefaultValStr(DefaultValStr), Description(Description), - IsHidden(IsHidden) { + DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) { assert((OptionType == "bool" || OptionType == "string" || OptionType == "int") && @@ -120,6 +122,10 @@ public: "Invalid value for integer command line option! Maybe incorrect " "parameters to the addCheckerOption or addPackageOption method?"); (void)Tmp; + + assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" || + DevelopmentStatus == "released") && + "Invalid development status!"); } }; @@ -241,7 +247,8 @@ public: /// non-compatibility mode. void addCheckerOption(StringRef OptionType, StringRef CheckerFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description, bool IsHidden = false); + StringRef Description, StringRef DevelopmentStatus, + bool IsHidden = false); /// Adds a package to the registry. void addPackage(StringRef FullName); @@ -257,7 +264,8 @@ public: /// non-compatibility mode. void addPackageOption(StringRef OptionType, StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description, bool IsHidden = false); + StringRef Description, StringRef DevelopmentStatus, + bool IsHidden = false); // FIXME: This *really* should be added to the frontend flag descriptions. /// Initializes a CheckerManager by calling the initialization functions for diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 36519c6d48..9658080457 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -288,9 +288,13 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Opts.ShowCheckerHelpAlpha = Args.hasArg(OPT_analyzer_checker_help_alpha); Opts.ShowCheckerHelpDeveloper = Args.hasArg(OPT_analyzer_checker_help_developer); + Opts.ShowCheckerOptionList = Args.hasArg(OPT_analyzer_checker_option_help); + Opts.ShowCheckerOptionAlphaList = + Args.hasArg(OPT_analyzer_checker_option_help_alpha); 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 = diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index a5f51ab7ae..da7aa7b82a 100644 --- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -249,7 +249,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) { } // Honor -analyzer-checker-option-help. - if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionDeveloperList) { + if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList || + AnOpts.ShowCheckerOptionDeveloperList) { ento::printCheckerConfigList(llvm::outs(), Clang->getFrontendOpts().Plugins, *Clang->getAnalyzerOpts(), diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index f3a4765c9e..3fd4c36947 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -180,12 +180,12 @@ CheckerRegistry::CheckerRegistry( addDependency(FULLNAME, DEPENDENCY); #define GET_CHECKER_OPTIONS -#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \ - addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN); +#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, DEVELOPMENT_STATUS, IS_HIDDEN) \ + addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, DEVELOPMENT_STATUS, IS_HIDDEN); #define GET_PACKAGE_OPTIONS -#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \ - addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN); +#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, DEVELOPMENT_STATUS, IS_HIDDEN) \ + addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, DEVELOPMENT_STATUS, IS_HIDDEN); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER_DEPENDENCY @@ -396,10 +396,12 @@ void CheckerRegistry::addPackageOption(StringRef OptionType, StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description, bool IsHidden) { + StringRef Description, + StringRef DevelopmentStatus, + bool IsHidden) { PackageOptions.emplace_back( PackageFullName, CmdLineOption{OptionType, OptionName, DefaultValStr, - Description, IsHidden}); + Description, DevelopmentStatus, IsHidden}); } void CheckerRegistry::addChecker(InitializationFunction Rfn, @@ -421,10 +423,12 @@ void CheckerRegistry::addCheckerOption(StringRef OptionType, StringRef CheckerFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description, bool IsHidden) { + StringRef Description, + StringRef DevelopmentStatus, + bool IsHidden) { CheckerOptions.emplace_back( CheckerFullName, CmdLineOption{OptionType, OptionName, DefaultValStr, - Description, IsHidden}); + Description, DevelopmentStatus, IsHidden}); } void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const { @@ -576,10 +580,14 @@ void CheckerRegistry::printCheckerOptionList(raw_ostream &Out) const { } } + auto Print = [] (llvm::raw_ostream &Out, StringRef FullOption, StringRef Desc) { + AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc}, + /*InitialPad*/ 2, + /*EntryWidth*/ 50, + /*MinLineWidth*/ 90); + Out << "\n\n"; + }; for (const std::pair &Entry : OptionMap) { - if (!AnOpts.ShowCheckerOptionDeveloperList && Entry.second.IsHidden) - continue; - const CmdLineOption &Option = Entry.second; std::string FullOption = (Entry.first + ":" + Option.OptionName).str(); @@ -588,10 +596,25 @@ void CheckerRegistry::printCheckerOptionList(raw_ostream &Out) const { (Option.DefaultValStr.empty() ? "\"\"" : Option.DefaultValStr) + ")") .str(); - AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc}, - /*InitialPad*/ 2, - /*EntryWidth*/ 50, - /*MinLineWidth*/ 90); - Out << "\n\n"; + // The list of these if branches is significant, we wouldn't like to + // display hidden alpha checker options for + // -analyzer-checker-option-help-alpha. + + if (Option.IsHidden) { + if (AnOpts.ShowCheckerOptionDeveloperList) + Print(Out, FullOption, Desc); + continue; + } + + if (Option.DevelopmentStatus == "alpha" || + Entry.first.startswith("alpha")) { + if (AnOpts.ShowCheckerOptionAlphaList) + Print(Out, FullOption, + llvm::Twine("(Enable only for development!) " + Desc).str()); + continue; + } + + if (AnOpts.ShowCheckerOptionList) + Print(Out, FullOption, Desc); } } diff --git a/test/Analysis/analyzer-checker-option-help.c b/test/Analysis/analyzer-checker-option-help.c index bc8ed09d43..5f95569e58 100644 --- a/test/Analysis/analyzer-checker-option-help.c +++ b/test/Analysis/analyzer-checker-option-help.c @@ -1,25 +1,87 @@ -// RUN: %clang_cc1 -analyzer-checker-option-help 2>&1 | FileCheck %s +// RUN: %clang_cc1 -analyzer-checker-option-help \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE + +// RUN: %clang_cc1 -analyzer-checker-option-help-alpha \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-ALPHA + +// RUN: %clang_cc1 -analyzer-checker-option-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-DEVELOPER // RUN: %clang_cc1 -analyzer-checker-option-help-developer \ -// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-HIDDEN +// RUN: -analyzer-checker-option-help-alpha \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-DEVELOPER-ALPHA + +// RUN: %clang_cc1 -analyzer-checker-option-help \ +// RUN: -analyzer-checker-option-help-alpha \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-ALPHA -// CHECK: OVERVIEW: Clang Static Analyzer Checker and Package Option List +// RUN: %clang_cc1 -analyzer-checker-option-help \ +// RUN: -analyzer-checker-option-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-DEVELOPER + +// RUN: %clang_cc1 -analyzer-checker-option-help \ +// RUN: -analyzer-checker-option-help-alpha \ +// RUN: -analyzer-checker-option-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-ALPHA-DEVELOPER + +// CHECK-STABLE: OVERVIEW: Clang Static Analyzer Checker and Package Option List // -// CHECK: USAGE: -analyzer-config +// CHECK-STABLE: USAGE: -analyzer-config // -// CHECK: -analyzer-config OPTION1=VALUE, -analyzer-config -// CHECK-SAME: OPTION2=VALUE, ... +// CHECK-STABLE: -analyzer-config OPTION1=VALUE, -analyzer-config +// CHECK-STABLE-SAME: OPTION2=VALUE, ... // -// CHECK: OPTIONS: +// CHECK-STABLE: OPTIONS: // -// CHECK: alpha.clone.CloneChecker:MinimumCloneComplexity -// CHECK-SAME: (int) Ensures that every clone has at least -// CHECK: the given complexity. Complexity is here -// CHECK: defined as the total amount of children -// CHECK: of a statement. This constraint assumes -// 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 +// CHECK-STABLE: cplusplus.Move:WarnOn +// CHECK-STABLE-SAME: (string) In non-aggressive mode, only warn +// CHECK-STABLLE: on use-after-move of local variables (or +// CHECK-STABLLE: local rvalue references) and of STL objects. +// CHECK-STABLLE: The former is possible because local variables +// CHECK-STABLLE: (or local rvalue references) are not tempting +// CHECK-STABLLE: their user to re-use the storage. The latter +// CHECK-STABLLE: is possible because STL objects are known +// CHECK-STABLLE: to end up in a valid but unspecified state +// CHECK-STABLLE: after the move and their state-reset methods +// CHECK-STABLLE: are also known, which allows us to predict +// CHECK-STABLLE: precisely when use-after-move is invalid. +// CHECK-STABLLE: Some STL objects are known to conform to +// CHECK-STABLLE: additional contracts after move, so they +// CHECK-STABLLE: are not tracked. However, smart pointers +// CHECK-STABLLE: specifically are tracked because we can +// CHECK-STABLLE: perform extra checking over them. In aggressive +// CHECK-STABLLE: mode, warn on any use-after-move because +// CHECK-STABLLE: the user has intentionally asked us to completely +// CHECK-STABLLE: eliminate use-after-move in his code. Values: +// CHECK-STABLLE: "KnownsOnly", "KnownsAndLocals", "All". +// CHECK-STABLLE: (default: KnownsAndLocals) + +// CHECK-STABLE-NOT: debug.AnalysisOrder:* +// CHECK-DEVELOPER: debug.AnalysisOrder:* +// CHECK-ALPHA-NOT: debug.AnalysisOrder:* + +// CHECK-STABLE-NOT: optin.cplusplus.UninitializedObject:IgnoreGuardedFields +// CHECK-DEVELOPER-NOT: optin.cplusplus.UninitializedObject:IgnoreGuardedFields +// CHECK-ALPHA: optin.cplusplus.UninitializedObject:IgnoreGuardedFields + +// CHECK-STABLE: optin.performance.Padding:AllowedPad +// CHECK-DEVELOPER-NOT: optin.performance.Padding:AllowedPad +// CHECK-ALPHA-NOT: optin.performance.Padding:AllowedPad + + +// CHECK-STABLE-ALPHA-NOT: debug.AnalysisOrder:* +// CHECK-DEVELOPER-ALPHA: debug.AnalysisOrder:* +// CHECK-STABLE-DEVELOPER: debug.AnalysisOrder:* + +// CHECK-STABLE-ALPHA: optin.cplusplus.UninitializedObject:IgnoreGuardedFields +// CHECK-DEVELOPER-ALPHA: optin.cplusplus.UninitializedObject:IgnoreGuardedFields +// CHECK-STABLE-DEVELOPER-NOT: optin.cplusplus.UninitializedObject:IgnoreGuardedFields + +// CHECK-STABLE-ALPHA: optin.performance.Padding:AllowedPad +// CHECK-DEVELOPER-ALPHA-NOT: optin.performance.Padding:AllowedPad +// CHECK-STABLE-DEVELOPER: optin.performance.Padding:AllowedPad + + +// CHECK-STABLE-ALPHA-DEVELOPER: debug.AnalysisOrder:* +// CHECK-STABLE-ALPHA-DEVELOPER: optin.cplusplus.UninitializedObject:IgnoreGuardedFields +// CHECK-STABLE-ALPHA-DEVELOPER: optin.performance.Padding:AllowedPad diff --git a/test/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp b/test/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp index c06a19df7d..77de3630ae 100644 --- a/test/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp +++ b/test/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp @@ -36,7 +36,8 @@ extern "C" void clang_registerCheckers(CheckerRegistry ®istry) { /*CheckerFullName*/ "example.MyChecker", /*OptionName*/ "ExampleOption", /*DefaultValStr*/ "false", - /*Description*/ "This is an example checker opt."); + /*Description*/ "This is an example checker opt.", + /*DevelopmentStage*/ "released"); } extern "C" const char clang_analyzerAPIVersionString[] = diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index 7c1827ec2e..7dd0895b76 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -110,6 +110,22 @@ static std::string getCheckerOptionType(const Record &R) { return ""; } +static std::string getDevelopmentStage(const Record &R) { + if (BitsInit *BI = R.getValueAsBitsInit("DevelopmentStage")) { + switch(getValueFromBitsInit(BI, R)) { + case 0: + return "alpha"; + case 1: + return "released"; + } + } + + PrintFatalError(R.getLoc(), + "unable to parse command line option type for " + + getCheckerFullName(&R)); + return ""; +} + static bool isHidden(const Record *R) { if (R->getValueAsBit("Hidden")) return true; @@ -149,6 +165,8 @@ static void printOption(llvm::raw_ostream &OS, StringRef FullName, OS.write_escaped(getStringValue(R, "Desc")) << "\", "; OS << '\"'; OS.write_escaped(getStringValue(R, "DefaultVal")) << "\", "; + OS << '\"'; + OS << getDevelopmentStage(R) << "\", "; if (!R.getValueAsBit("Hidden")) OS << "false";