summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorKristof Umann <dkszelethus@gmail.com>2019-03-08 16:00:42 +0000
committerKristof Umann <dkszelethus@gmail.com>2019-03-08 16:00:42 +0000
commit748c139adebf58b144bf4ecc2a2333d9ad66ecdc (patch)
treeb7cc366136d420ea201758a95e9db3cd1def8fac /clang/lib/StaticAnalyzer
parent2827349c9d7e12fc05e6213c024d50bf59294cb1 (diff)
downloadbcm5719-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')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp8
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp38
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp12
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp6
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp9
-rw-r--r--clang/lib/StaticAnalyzer/Core/CheckerManager.cpp10
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..
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud