Expose the name of the checker producing each diagnostic message.
Summary:
In clang-tidy we'd like to know the name of the checker producing each
diagnostic message. PathDiagnostic has BugType and Category fields, which are
both arbitrary human-readable strings, but we need to know the exact name of the
checker in the form that can be used in the CheckersControlList option to
enable/disable the specific checker.
This patch adds the CheckName field to the CheckerBase class, and sets it in
the CheckerManager::registerChecker() method, which gets them from the
CheckerRegistry.
Checkers that implement multiple checks have to store the names of each check
in the respective registerXXXChecker method.
Reviewers: jordan_rose, krememek
Reviewed By: jordan_rose
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D2557
llvm-svn: 201186
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 0ee4a43..5706364 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -46,8 +46,18 @@
DefaultBool check_vfork;
DefaultBool check_FloatLoopCounter;
DefaultBool check_UncheckedReturn;
+
+ CheckName checkName_gets;
+ CheckName checkName_getpw;
+ CheckName checkName_mktemp;
+ CheckName checkName_mkstemp;
+ CheckName checkName_strcpy;
+ CheckName checkName_rand;
+ CheckName checkName_vfork;
+ CheckName checkName_FloatLoopCounter;
+ CheckName checkName_UncheckedReturn;
};
-
+
class WalkAST : public StmtVisitor<WalkAST> {
BugReporter &BR;
AnalysisDeclContext* AC;
@@ -281,7 +291,7 @@
PathDiagnosticLocation FSLoc =
PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter,
bugType, "Security", os.str(),
FSLoc, ranges);
}
@@ -316,7 +326,7 @@
// Issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_gets,
"Potential buffer overflow in call to 'gets'",
"Security",
"Call to function 'gets' is extremely insecure as it can "
@@ -356,7 +366,7 @@
// Issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_getpw,
"Potential buffer overflow in call to 'getpw'",
"Security",
"The getpw() function is dangerous as it may overflow the "
@@ -397,7 +407,7 @@
// Issue a waring.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_mktemp,
"Potential insecure temporary file in call 'mktemp'",
"Security",
"Call to function 'mktemp' is insecure as it always "
@@ -483,7 +493,7 @@
out << " used as a suffix";
}
out << ')';
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_mkstemp,
"Insecure temporary file creation", "Security",
out.str(), CELoc, strArg->getSourceRange());
}
@@ -504,7 +514,7 @@
// Issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
"Potential insecure memory buffer bounds restriction in "
"call 'strcpy'",
"Security",
@@ -531,7 +541,7 @@
// Issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
"Potential insecure memory buffer bounds restriction in "
"call 'strcat'",
"Security",
@@ -609,8 +619,9 @@
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(),
- CELoc, CE->getCallee()->getSourceRange());
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(),
+ "Security", os2.str(), CELoc,
+ CE->getCallee()->getSourceRange());
}
//===----------------------------------------------------------------------===//
@@ -633,7 +644,7 @@
// Issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand,
"'random' is not a secure random number generator",
"Security",
"The 'random' function produces a sequence of values that "
@@ -653,7 +664,7 @@
// All calls to vfork() are insecure, issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(),
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork,
"Potential insecure implementation-specific behavior in "
"call 'vfork'",
"Security",
@@ -724,8 +735,9 @@
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(),
- CELoc, CE->getCallee()->getSourceRange());
+ BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(),
+ "Security", os2.str(), CELoc,
+ CE->getCallee()->getSourceRange());
}
//===----------------------------------------------------------------------===//
@@ -745,10 +757,13 @@
};
}
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
- mgr.registerChecker<SecuritySyntaxChecker>()->filter.check_##name = true;\
-}
+#define REGISTER_CHECKER(name) \
+ void ento::register##name(CheckerManager &mgr) { \
+ SecuritySyntaxChecker *checker = \
+ mgr.registerChecker<SecuritySyntaxChecker>(); \
+ checker->filter.check_##name = true; \
+ checker->filter.checkName_##name = mgr.getCurrentCheckName(); \
+ }
REGISTER_CHECKER(gets)
REGISTER_CHECKER(getpw)