diff options
author | Kristof Umann <dkszelethus@gmail.com> | 2019-03-08 16:00:42 +0000 |
---|---|---|
committer | Kristof Umann <dkszelethus@gmail.com> | 2019-03-08 16:00:42 +0000 |
commit | 748c139adebf58b144bf4ecc2a2333d9ad66ecdc (patch) | |
tree | b7cc366136d420ea201758a95e9db3cd1def8fac /clang/lib/StaticAnalyzer | |
parent | 2827349c9d7e12fc05e6213c024d50bf59294cb1 (diff) | |
download | bcm5719-llvm-748c139adebf58b144bf4ecc2a2333d9ad66ecdc.tar.gz bcm5719-llvm-748c139adebf58b144bf4ecc2a2333d9ad66ecdc.zip |
[analyzer] Emit an error rather than assert on invalid checker option input
Asserting on invalid input isn't very nice, hence the patch to emit an error
instead.
This is the first of many patches to overhaul the way we handle checker options.
Differential Revision: https://reviews.llvm.org/D57850
llvm-svn: 355704
Diffstat (limited to 'clang/lib/StaticAnalyzer')
6 files changed, 55 insertions, 28 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index 6be66d20afc..a7ca814c8f9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -1086,14 +1086,10 @@ bool ObjCDeallocChecker::isNibLoadedIvarWithoutRetain( } void ento::registerObjCDeallocChecker(CheckerManager &Mgr) { - const LangOptions &LangOpts = Mgr.getLangOpts(); - // These checker only makes sense under MRR. - if (LangOpts.getGC() == LangOptions::GCOnly || LangOpts.ObjCAutoRefCount) - return; - Mgr.registerChecker<ObjCDeallocChecker>(); } bool ento::shouldRegisterObjCDeallocChecker(const LangOptions &LO) { - return true; + // These checker only makes sense under MRR. + return LO.getGC() != LangOptions::GCOnly && !LO.ObjCAutoRefCount; } diff --git a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 84018c5c39b..11a33e50bf5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -27,6 +27,13 @@ using namespace ento; namespace { class CloneChecker : public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> { +public: + // Checker options. + int MinComplexity; + bool ReportNormalClones; + StringRef IgnoredFilesPattern; + +private: mutable CloneDetector Detector; mutable std::unique_ptr<BugType> BT_Exact, BT_Suspicious; @@ -62,19 +69,6 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU, // At this point, every statement in the translation unit has been analyzed by // the CloneDetector. The only thing left to do is to report the found clones. - int MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption( - this, "MinimumCloneComplexity", 50); - assert(MinComplexity >= 0); - - bool ReportSuspiciousClones = Mgr.getAnalyzerOptions() - .getCheckerBooleanOption(this, "ReportSuspiciousClones", true); - - bool ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption( - this, "ReportNormalClones", true); - - StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions() - .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 // because reportSuspiciousClones() wants to search them for errors. @@ -86,8 +80,7 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU, MinComplexityConstraint(MinComplexity), RecursiveCloneTypeIIVerifyConstraint(), OnlyLargestCloneConstraint()); - if (ReportSuspiciousClones) - reportSuspiciousClones(BR, Mgr, AllCloneGroups); + reportSuspiciousClones(BR, Mgr, AllCloneGroups); // We are done for this translation unit unless we also need to report normal // clones. @@ -199,7 +192,20 @@ void CloneChecker::reportSuspiciousClones( //===----------------------------------------------------------------------===// void ento::registerCloneChecker(CheckerManager &Mgr) { - Mgr.registerChecker<CloneChecker>(); + auto *Checker = Mgr.registerChecker<CloneChecker>(); + + Checker->MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption( + Checker, "MinimumCloneComplexity", 50); + + if (Checker->MinComplexity < 0) + Mgr.reportInvalidCheckerOptionValue( + Checker, "MinimumCloneComplexity", "a non-negative value"); + + Checker->ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption( + Checker, "ReportNormalClones", true); + + Checker->IgnoredFilesPattern = Mgr.getAnalyzerOptions() + .getCheckerStringOption(Checker, "IgnoredFilesPattern", ""); } bool ento::shouldRegisterCloneChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index eab3fa3af95..545f310a51b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ExprCXX.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -186,13 +187,17 @@ private: AggressivenessKind Aggressiveness; public: - void setAggressiveness(StringRef Str) { + void setAggressiveness(StringRef Str, CheckerManager &Mgr) { Aggressiveness = llvm::StringSwitch<AggressivenessKind>(Str) .Case("KnownsOnly", AK_KnownsOnly) .Case("KnownsAndLocals", AK_KnownsAndLocals) .Case("All", AK_All) - .Default(AK_KnownsAndLocals); // A sane default. + .Default(AK_Invalid); + + if (Aggressiveness == AK_Invalid) + Mgr.reportInvalidCheckerOptionValue(this, "WarnOn", + "either \"KnownsOnly\", \"KnownsAndLocals\" or \"All\" string value"); }; private: @@ -735,7 +740,8 @@ void MoveChecker::printState(raw_ostream &Out, ProgramStateRef State, void ento::registerMoveChecker(CheckerManager &mgr) { MoveChecker *chk = mgr.registerChecker<MoveChecker>(); chk->setAggressiveness( - mgr.getAnalyzerOptions().getCheckerStringOption(chk, "WarnOn", "")); + mgr.getAnalyzerOptions().getCheckerStringOption(chk, "WarnOn", + "KnownsAndLocals"), mgr); } bool ento::shouldRegisterMoveChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index df5b46ebd2e..abc90986f40 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -348,8 +349,9 @@ void ento::registerPaddingChecker(CheckerManager &Mgr) { auto *Checker = Mgr.registerChecker<PaddingChecker>(); Checker->AllowedPad = Mgr.getAnalyzerOptions() .getCheckerIntegerOption(Checker, "AllowedPad", 24); - assert(Checker->AllowedPad >= 0 && - "AllowedPad option should be non-negative"); + if (Checker->AllowedPad < 0) + Mgr.reportInvalidCheckerOptionValue( + Checker, "AllowedPad", "a non-negative value"); } 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 53da456fd53..187e868fba0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -20,6 +20,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "UninitializedObject.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -618,10 +619,16 @@ void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) { Chk, "CheckPointeeInitialization", /*DefaultVal*/ false); ChOpts.IgnoredRecordsWithFieldPattern = AnOpts.getCheckerStringOption(Chk, "IgnoreRecordsWithField", - /*DefaultVal*/ ""); + /*DefaultVal*/ "\"\""); ChOpts.IgnoreGuardedFields = AnOpts.getCheckerBooleanOption(Chk, "IgnoreGuardedFields", /*DefaultVal*/ false); + + std::string ErrorMsg; + if (!llvm::Regex(ChOpts.IgnoredRecordsWithFieldPattern).isValid(ErrorMsg)) + Mgr.reportInvalidCheckerOptionValue(Chk, "IgnoreRecordsWithField", + "a valid regex, building failed with error message " + "\"" + ErrorMsg + "\""); } bool ento::shouldRegisterUninitializedObjectChecker(const LangOptions &LO) { diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp index c874ed2ddcd..53d872021af 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -15,6 +15,7 @@ #include "clang/AST/Stmt.h" #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -58,6 +59,15 @@ void CheckerManager::finishedCheckerRegistration() { #endif } +void CheckerManager::reportInvalidCheckerOptionValue( + const CheckerBase *C, StringRef OptionName, StringRef ExpectedValueDesc) { + + Context.getDiagnostics() + .Report(diag::err_analyzer_checker_option_invalid_input) + << (llvm::Twine() + C->getTagDescription() + ":" + OptionName).str() + << ExpectedValueDesc; +} + //===----------------------------------------------------------------------===// // Functions for running checkers for AST traversing.. //===----------------------------------------------------------------------===// |