diff options
author | Kristof Umann <dkszelethus@gmail.com> | 2019-03-04 00:28:16 +0000 |
---|---|---|
committer | Kristof Umann <dkszelethus@gmail.com> | 2019-03-04 00:28:16 +0000 |
commit | 088b1c9cdcdb3d83fa730c1fcbae6db8252fe76d (patch) | |
tree | 3ff1101103765384e7f37bb997ee6cd88faf4fe1 /clang/lib/StaticAnalyzer | |
parent | 195a62e9ae50594e469398631a24f4bc26061c56 (diff) | |
download | bcm5719-llvm-088b1c9cdcdb3d83fa730c1fcbae6db8252fe76d.tar.gz bcm5719-llvm-088b1c9cdcdb3d83fa730c1fcbae6db8252fe76d.zip |
[analyzer] Enable subcheckers to possess checker options
Under the term "subchecker", I mean checkers that do not have a checker class on
their own, like unix.MallocChecker to unix.DynamicMemoryModeling.
Since a checker object was required in order to retrieve checker options,
subcheckers couldn't possess options on their own.
This patch is also an excuse to change the argument order of getChecker*Option,
it always bothered me, now it resembles the actual command line argument
(checkername:option=value).
Differential Revision: https://reviews.llvm.org/D57579
llvm-svn: 355297
Diffstat (limited to 'clang/lib/StaticAnalyzer')
12 files changed, 73 insertions, 49 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index 8dc879bf129..05e0cd81ac8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -44,8 +44,8 @@ class AnalysisOrderChecker check::LiveSymbols> { bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const { - return Opts.getCheckerBooleanOption("*", false, this) || - Opts.getCheckerBooleanOption(CallbackName, false, this); + return Opts.getCheckerBooleanOption(this, "*", false) || + Opts.getCheckerBooleanOption(this, CallbackName, false); } bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 42b26147245..84018c5c39b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -63,17 +63,17 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU, // the CloneDetector. The only thing left to do is to report the found clones. int MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption( - "MinimumCloneComplexity", 50, this); + this, "MinimumCloneComplexity", 50); assert(MinComplexity >= 0); bool ReportSuspiciousClones = Mgr.getAnalyzerOptions() - .getCheckerBooleanOption("ReportSuspiciousClones", true, this); + .getCheckerBooleanOption(this, "ReportSuspiciousClones", true); bool ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption( - "ReportNormalClones", true, this); + this, "ReportNormalClones", true); StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions() - .getCheckerStringOption("IgnoredFilesPattern", "", this); + .getCheckerStringOption(this, "IgnoredFilesPattern", ""); // Let the CloneDetector create a list of clones from all the analyzed // statements. We don't filter for matching variable patterns at this point diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index 76103f81a68..cb7ba73a091 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -1397,8 +1397,8 @@ void ento::registerNonLocalizedStringChecker(CheckerManager &mgr) { NonLocalizedStringChecker *checker = mgr.registerChecker<NonLocalizedStringChecker>(); checker->IsAggressive = - mgr.getAnalyzerOptions().getCheckerBooleanOption("AggressiveReport", - false, checker); + mgr.getAnalyzerOptions().getCheckerBooleanOption( + checker, "AggressiveReport", false); } bool ento::shouldRegisterNonLocalizedStringChecker(const LangOptions &LO) { @@ -1409,7 +1409,8 @@ void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) { mgr.registerChecker<EmptyLocalizationContextChecker>(); } -bool ento::shouldRegisterEmptyLocalizationContextChecker(const LangOptions &LO) { +bool ento::shouldRegisterEmptyLocalizationContextChecker( + const LangOptions &LO) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 7ab67213d58..f7ad8fac176 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -3098,7 +3098,7 @@ void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) { void ento::registerDynamicMemoryModeling(CheckerManager &mgr) { auto *checker = mgr.registerChecker<MallocChecker>(); checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Optimistic", false, checker); + checker, "Optimistic", false); } bool ento::shouldRegisterDynamicMemoryModeling(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 2575302ae22..2185561fcda 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -82,10 +82,10 @@ void ento::registerMmapWriteExecChecker(CheckerManager &mgr) { mgr.registerChecker<MmapWriteExecChecker>(); Mwec->ProtExecOv = mgr.getAnalyzerOptions() - .getCheckerIntegerOption("MmapProtExec", 0x04, Mwec); + .getCheckerIntegerOption(Mwec, "MmapProtExec", 0x04); Mwec->ProtReadOv = mgr.getAnalyzerOptions() - .getCheckerIntegerOption("MmapProtRead", 0x01, Mwec); + .getCheckerIntegerOption(Mwec, "MmapProtRead", 0x01); } bool ento::shouldRegisterMmapWriteExecChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index ef6a3df2d28..eab3fa3af95 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -735,7 +735,7 @@ void MoveChecker::printState(raw_ostream &Out, ProgramStateRef State, void ento::registerMoveChecker(CheckerManager &mgr) { MoveChecker *chk = mgr.registerChecker<MoveChecker>(); chk->setAggressiveness( - mgr.getAnalyzerOptions().getCheckerStringOption("WarnOn", "", chk)); + mgr.getAnalyzerOptions().getCheckerStringOption(chk, "WarnOn", "")); } bool ento::shouldRegisterMoveChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index e1fbcc670c5..e5beb0dad2f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -1208,7 +1208,7 @@ bool ento::shouldRegisterNullabilityBase(const LangOptions &LO) { checker->NoDiagnoseCallsToSystemHeaders = \ checker->NoDiagnoseCallsToSystemHeaders || \ mgr.getAnalyzerOptions().getCheckerBooleanOption( \ - "NoDiagnoseCallsToSystemHeaders", false, checker, true); \ + checker, "NoDiagnoseCallsToSystemHeaders", false, true); \ } \ \ bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \ diff --git a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp index 22b5485c659..33119c6a18c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp @@ -346,7 +346,7 @@ void ento::registerNumberObjectConversionChecker(CheckerManager &Mgr) { NumberObjectConversionChecker *Chk = Mgr.registerChecker<NumberObjectConversionChecker>(); Chk->Pedantic = - Mgr.getAnalyzerOptions().getCheckerBooleanOption("Pedantic", false, Chk); + Mgr.getAnalyzerOptions().getCheckerBooleanOption(Chk, "Pedantic", false); } bool ento::shouldRegisterNumberObjectConversionChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index d4d4459b37b..df5b46ebd2e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -32,17 +32,14 @@ namespace { class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> { private: mutable std::unique_ptr<BugType> PaddingBug; - mutable int64_t AllowedPad; mutable BugReporter *BR; public: + int64_t AllowedPad; + void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, BugReporter &BRArg) const { BR = &BRArg; - AllowedPad = - MGR.getAnalyzerOptions() - .getCheckerIntegerOption("AllowedPad", 24, this); - assert(AllowedPad >= 0 && "AllowedPad option should be non-negative"); // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We @@ -348,7 +345,11 @@ public: } // namespace void ento::registerPaddingChecker(CheckerManager &Mgr) { - Mgr.registerChecker<PaddingChecker>(); + auto *Checker = Mgr.registerChecker<PaddingChecker>(); + Checker->AllowedPad = Mgr.getAnalyzerOptions() + .getCheckerIntegerOption(Checker, "AllowedPad", 24); + assert(Checker->AllowedPad >= 0 && + "AllowedPad option should be non-negative"); } bool ento::shouldRegisterPaddingChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp index 4e420a7c773..53da456fd53 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -611,18 +611,17 @@ void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) { UninitObjCheckerOptions &ChOpts = Chk->Opts; ChOpts.IsPedantic = - AnOpts.getCheckerBooleanOption("Pedantic", /*DefaultVal*/ false, Chk); - ChOpts.ShouldConvertNotesToWarnings = - AnOpts.getCheckerBooleanOption("NotesAsWarnings", - /*DefaultVal*/ false, Chk); + AnOpts.getCheckerBooleanOption(Chk, "Pedantic", /*DefaultVal*/ false); + ChOpts.ShouldConvertNotesToWarnings = AnOpts.getCheckerBooleanOption( + Chk, "NotesAsWarnings", /*DefaultVal*/ false); ChOpts.CheckPointeeInitialization = AnOpts.getCheckerBooleanOption( - "CheckPointeeInitialization", /*DefaultVal*/ false, Chk); + Chk, "CheckPointeeInitialization", /*DefaultVal*/ false); ChOpts.IgnoredRecordsWithFieldPattern = - AnOpts.getCheckerStringOption("IgnoreRecordsWithField", - /*DefaultVal*/ "", Chk); + AnOpts.getCheckerStringOption(Chk, "IgnoreRecordsWithField", + /*DefaultVal*/ ""); ChOpts.IgnoreGuardedFields = - AnOpts.getCheckerBooleanOption("IgnoreGuardedFields", - /*DefaultVal*/ false, Chk); + AnOpts.getCheckerBooleanOption(Chk, "IgnoreGuardedFields", + /*DefaultVal*/ false); } bool ento::shouldRegisterUninitializedObjectChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp index d70c3d26be1..c3a9ef8b56a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -279,8 +279,8 @@ void ento::registerVirtualCallChecker(CheckerManager &mgr) { VirtualCallChecker *checker = mgr.registerChecker<VirtualCallChecker>(); checker->IsPureOnly = - mgr.getAnalyzerOptions().getCheckerBooleanOption("PureOnly", false, - checker); + mgr.getAnalyzerOptions().getCheckerBooleanOption( + checker, "PureOnly", false); } bool ento::shouldRegisterVirtualCallChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 7ee2b9dd215..ee670fb45a7 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -101,18 +101,14 @@ AnalyzerOptions::mayInlineCXXMemberFunction( return *K >= Param; } -StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName, +StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName, + StringRef OptionName, StringRef DefaultVal, - const CheckerBase *C, - bool SearchInParents) const { - assert(C); - // Search for a package option if the option for the checker is not specified - // and search in parents is enabled. - StringRef CheckerName = C->getTagDescription(); - + bool SearchInParents ) const { assert(!CheckerName.empty() && "Empty checker name! Make sure the checker object (including it's " "bases!) if fully initialized before calling this function!"); + ConfigTable::const_iterator E = Config.end(); do { ConfigTable::const_iterator I = @@ -127,29 +123,56 @@ StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName, return DefaultVal; } -bool AnalyzerOptions::getCheckerBooleanOption(StringRef Name, bool DefaultVal, - const CheckerBase *C, - bool SearchInParents) const { +StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C, + StringRef OptionName, + StringRef DefaultVal, + bool SearchInParents ) const { + return getCheckerStringOption( + C->getTagDescription(), OptionName, DefaultVal, SearchInParents); +} + +bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName, + StringRef OptionName, + bool DefaultVal, + bool SearchInParents ) const { // FIXME: We should emit a warning here if the value is something other than // "true", "false", or the empty string (meaning the default value), // but the AnalyzerOptions doesn't have access to a diagnostic engine. - assert(C); return llvm::StringSwitch<bool>( - getCheckerStringOption(Name, DefaultVal ? "true" : "false", C, + getCheckerStringOption(CheckerName, OptionName, + DefaultVal ? "true" : "false", SearchInParents)) .Case("true", true) .Case("false", false) .Default(DefaultVal); } -int AnalyzerOptions::getCheckerIntegerOption(StringRef Name, int DefaultVal, - const CheckerBase *C, - bool SearchInParents) const { +bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C, + StringRef OptionName, + bool DefaultVal, + bool SearchInParents ) const { + return getCheckerBooleanOption( + C->getTagDescription(), OptionName, DefaultVal, SearchInParents); +} + +int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName, + StringRef OptionName, + int DefaultVal, + bool SearchInParents ) const { int Ret = DefaultVal; - bool HasFailed = getCheckerStringOption(Name, std::to_string(DefaultVal), C, + bool HasFailed = getCheckerStringOption(CheckerName, OptionName, + std::to_string(DefaultVal), SearchInParents) .getAsInteger(10, Ret); assert(!HasFailed && "analyzer-config option should be numeric"); (void)HasFailed; return Ret; } + +int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C, + StringRef OptionName, + int DefaultVal, + bool SearchInParents ) const { + return getCheckerIntegerOption( + C->getTagDescription(), OptionName, DefaultVal, SearchInParents); +} |