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)