r201186 - Expose the name of the checker producing each diagnostic message.

Alexander Kornienko alexfh at google.com
Tue Feb 11 13:49:22 PST 2014


Author: alexfh
Date: Tue Feb 11 15:49:21 2014
New Revision: 201186

URL: http://llvm.org/viewvc/llvm-project?rev=201186&view=rev
Log:
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

Modified:
    cfe/trunk/examples/analyzer-plugin/MainCallChecker.cpp
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp

Modified: cfe/trunk/examples/analyzer-plugin/MainCallChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/analyzer-plugin/MainCallChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/examples/analyzer-plugin/MainCallChecker.cpp (original)
+++ cfe/trunk/examples/analyzer-plugin/MainCallChecker.cpp Tue Feb 11 15:49:21 2014
@@ -35,7 +35,7 @@ void MainCallChecker::checkPreStmt(const
       return;
 
     if (!BT)
-      BT.reset(new BugType("call to main", "example analyzer plugin"));
+      BT.reset(new BugType(this, "call to main", "example analyzer plugin"));
 
     BugReport *report = new BugReport(*BT, BT->getName(), N);
     report->addRange(Callee->getSourceRange());

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Tue Feb 11 15:49:21 2014
@@ -19,6 +19,7 @@
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -463,7 +464,12 @@ public:
   /// reports.
   void emitReport(BugReport *R);
 
-  void EmitBasicReport(const Decl *DeclWithIssue,
+  void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker,
+                       StringRef BugName, StringRef BugCategory,
+                       StringRef BugStr, PathDiagnosticLocation Loc,
+                       ArrayRef<SourceRange> Ranges = None);
+
+  void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
                        StringRef BugName, StringRef BugCategory,
                        StringRef BugStr, PathDiagnosticLocation Loc,
                        ArrayRef<SourceRange> Ranges = None);
@@ -473,7 +479,8 @@ private:
 
   /// \brief Returns a BugType that is associated with the given name and
   /// category.
-  BugType *getBugTypeForName(StringRef name, StringRef category);
+  BugType *getBugTypeForName(CheckName CheckName, StringRef name,
+                             StringRef category);
 };
 
 // FIXME: Get rid of GRBugReporter.  It's the wrong abstraction.

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h Tue Feb 11 15:49:21 2014
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
 #include "llvm/ADT/FoldingSet.h"
 #include <string>
 
@@ -29,20 +30,25 @@ class ExprEngine;
 
 class BugType {
 private:
+  const CheckName CheckName;
   const std::string Name;
   const std::string Category;
   bool SuppressonSink;
 
   virtual void anchor();
 public:
-  BugType(StringRef name, StringRef cat)
-    : Name(name), Category(cat), SuppressonSink(false) {}
+  BugType(class CheckName Check, StringRef name, StringRef cat)
+      : CheckName(Check), Name(name), Category(cat), SuppressonSink(false) {}
+  BugType(const CheckerBase *checker, StringRef name, StringRef cat)
+      : CheckName(checker->getCheckName()), Name(name), Category(cat),
+        SuppressonSink(false) {}
   virtual ~BugType() {}
 
   // FIXME: Should these be made strings as well?
   StringRef getName() const { return Name; }
   StringRef getCategory() const { return Category; }
-  
+  StringRef getCheckName() const { return CheckName.getName(); }
+
   /// isSuppressOnSink - Returns true if bug reports associated with this bug
   ///  type should be suppressed if the end node of the report is post-dominated
   ///  by a sink node.
@@ -56,12 +62,17 @@ class BuiltinBug : public BugType {
   const std::string desc;
   virtual void anchor();
 public:
-  BuiltinBug(const char *name, const char *description)
-    : BugType(name, categories::LogicError), desc(description) {}
-  
-  BuiltinBug(const char *name)
-    : BugType(name, categories::LogicError), desc(name) {}
-  
+  BuiltinBug(class CheckName CheckName, const char *name,
+             const char *description)
+      : BugType(CheckName, name, categories::LogicError), desc(description) {}
+
+  BuiltinBug(const CheckerBase *checker, const char *name,
+             const char *description)
+      : BugType(checker, name, categories::LogicError), desc(description) {}
+
+  BuiltinBug(const CheckerBase *checker, const char *name)
+      : BugType(checker, name, categories::LogicError), desc(name) {}
+
   StringRef getDescription() const { return desc; }
 };
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h Tue Feb 11 15:49:21 2014
@@ -710,6 +710,7 @@ public:
 ///  diagnostic.  It represents an ordered-collection of PathDiagnosticPieces,
 ///  each which represent the pieces of the path.
 class PathDiagnostic : public llvm::FoldingSetNode {
+  std::string CheckName;
   const Decl *DeclWithIssue;
   std::string BugType;
   std::string VerboseDesc;
@@ -730,8 +731,8 @@ class PathDiagnostic : public llvm::Fold
 
   PathDiagnostic() LLVM_DELETED_FUNCTION;
 public:
-  PathDiagnostic(const Decl *DeclWithIssue, StringRef bugtype,
-                 StringRef verboseDesc, StringRef shortDesc,
+  PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
+                 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
                  StringRef category, PathDiagnosticLocation LocationToUnique,
                  const Decl *DeclToUnique);
 
@@ -788,6 +789,7 @@ public:
   StringRef getShortDescription() const {
     return ShortDesc.empty() ? VerboseDesc : ShortDesc;
   }
+  StringRef getCheckName() const { return CheckName; }
   StringRef getBugType() const { return BugType; }
   StringRef getCategory() const { return Category; }
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Tue Feb 11 15:49:21 2014
@@ -453,14 +453,18 @@ public:
 } // end eval namespace
 
 class CheckerBase : public ProgramPointTag {
+  CheckName Name;
+  friend class ::clang::ento::CheckerManager;
+
 public:
   StringRef getTagDescription() const;
+  CheckName getCheckName() const;
 
   /// See CheckerManager::runCheckersForPrintState.
   virtual void printState(raw_ostream &Out, ProgramStateRef State,
                           const char *NL, const char *Sep) const { }
 };
-  
+
 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
           typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
           typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Tue Feb 11 15:49:21 2014
@@ -29,6 +29,7 @@ namespace clang {
 
 namespace ento {
   class CheckerBase;
+  class CheckerRegistry;
   class ExprEngine;
   class AnalysisManager;
   class BugReporter;
@@ -131,9 +132,26 @@ enum PointerEscapeKind {
   PSK_EscapeOther
 };
 
+// This wrapper is used to ensure that only StringRefs originating from the
+// CheckerRegistry are used as check names. We want to make sure all check
+// name strings have a lifetime that keeps them alive at least until the path
+// diagnostics have been processed.
+class CheckName {
+  StringRef Name;
+  friend class ::clang::ento::CheckerRegistry;
+  explicit CheckName(StringRef Name) : Name(Name) {}
+
+public:
+  CheckName() {}
+  CheckName(const CheckName &Other) : Name(Other.Name) {}
+  StringRef getName() const { return Name; }
+};
+
 class CheckerManager {
   const LangOptions LangOpts;
   AnalyzerOptionsRef AOptions;
+  CheckName CurrentCheckName;
+
 public:
   CheckerManager(const LangOptions &langOpts,
                  AnalyzerOptionsRef AOptions)
@@ -142,6 +160,9 @@ public:
 
   ~CheckerManager();
 
+  void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
+  CheckName getCurrentCheckName() const { return CurrentCheckName; }
+
   bool hasPathSensitiveCheckers() const;
 
   void finishedCheckerRegistration();
@@ -168,6 +189,7 @@ public:
       return static_cast<CHECKER *>(ref); // already registered.
 
     CHECKER *checker = new CHECKER();
+    checker->Name = CurrentCheckName;
     CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
     CHECKER::_register(checker, *this);
     ref = checker;
@@ -182,6 +204,7 @@ public:
       return static_cast<CHECKER *>(ref); // already registered.
 
     CHECKER *checker = new CHECKER(AOpts);
+    checker->Name = CurrentCheckName;
     CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
     CHECKER::_register(checker, *this);
     ref = checker;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp Tue Feb 11 15:49:21 2014
@@ -112,7 +112,7 @@ void AnalyzerStatsChecker::checkEndAnaly
       << " | Empty WorkList: "
       << (Eng.hasEmptyWorkList() ? "yes" : "no");
 
-  B.EmitBasicReport(D, "Analyzer Statistics", "Internal Statistics",
+  B.EmitBasicReport(D, this, "Analyzer Statistics", "Internal Statistics",
                     output.str(), PathDiagnosticLocation(D, SM));
 
   // Emit warning for each block we bailed out on.
@@ -129,7 +129,7 @@ void AnalyzerStatsChecker::checkEndAnaly
       outputI << "(" << NameOfRootFunction << ")" <<
                  ": The analyzer generated a sink at this point";
       B.EmitBasicReport(
-          D, "Sink Point", "Internal Statistics", outputI.str(),
+          D, this, "Sink Point", "Internal Statistics", outputI.str(),
           PathDiagnosticLocation::createBegin(CS->getStmt(), SM, LC));
     }
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp Tue Feb 11 15:49:21 2014
@@ -66,8 +66,9 @@ void ArrayBoundChecker::checkLocation(SV
       return;
   
     if (!BT)
-      BT.reset(new BuiltinBug("Out-of-bound array access",
-                       "Access out-of-bound array element (buffer overflow)"));
+      BT.reset(new BuiltinBug(
+          this, "Out-of-bound array access",
+          "Access out-of-bound array element (buffer overflow)"));
 
     // FIXME: It would be nice to eventually make this diagnostic more clear,
     // e.g., by referencing the original declaration or by saying *why* this

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp Tue Feb 11 15:49:21 2014
@@ -187,7 +187,7 @@ void ArrayBoundCheckerV2::reportOOB(Chec
     return;
 
   if (!BT)
-    BT.reset(new BuiltinBug("Out-of-bound access"));
+    BT.reset(new BuiltinBug(this, "Out-of-bound access"));
 
   // FIXME: This diagnostics are preliminary.  We should get far better
   // diagnostics for explaining buffer overruns.
@@ -311,7 +311,6 @@ RegionRawOffsetV2 RegionRawOffsetV2::com
   return RegionRawOffsetV2();
 }
 
-
 void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) {
   mgr.registerChecker<ArrayBoundCheckerV2>();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Tue Feb 11 15:49:21 2014
@@ -39,7 +39,8 @@ using namespace ento;
 namespace {
 class APIMisuse : public BugType {
 public:
-  APIMisuse(const char* name) : BugType(name, "API Misuse (Apple)") {}
+  APIMisuse(const CheckerBase *checker, const char *name)
+      : BugType(checker, name, "API Misuse (Apple)") {}
 };
 } // end anonymous namespace
 
@@ -191,7 +192,7 @@ void NilArgChecker::generateBugReport(Ex
                                       const Expr *E,
                                       CheckerContext &C) const {
   if (!BT)
-    BT.reset(new APIMisuse("nil argument"));
+    BT.reset(new APIMisuse(this, "nil argument"));
 
   BugReport *R = new BugReport(*BT, Msg, N);
   R->addRange(Range);
@@ -483,8 +484,8 @@ void CFNumberCreateChecker::checkPreStmt
       << " bits of the input integer will be lost.";
 
     if (!BT)
-      BT.reset(new APIMisuse("Bad use of CFNumberCreate"));
-    
+      BT.reset(new APIMisuse(this, "Bad use of CFNumberCreate"));
+
     BugReport *report = new BugReport(*BT, os.str(), N);
     report->addRange(CE->getArg(2)->getSourceRange());
     C.emitReport(report);
@@ -522,8 +523,8 @@ void CFRetainReleaseChecker::checkPreStm
     Retain = &Ctx.Idents.get("CFRetain");
     Release = &Ctx.Idents.get("CFRelease");
     MakeCollectable = &Ctx.Idents.get("CFMakeCollectable");
-    BT.reset(
-      new APIMisuse("null passed to CFRetain/CFRelease/CFMakeCollectable"));
+    BT.reset(new APIMisuse(
+        this, "null passed to CFRetain/CFRelease/CFMakeCollectable"));
   }
 
   // Check if we called CFRetain/CFRelease/CFMakeCollectable.
@@ -600,9 +601,9 @@ void ClassReleaseChecker::checkPreObjCMe
                                               CheckerContext &C) const {
   
   if (!BT) {
-    BT.reset(new APIMisuse("message incorrectly sent to class instead of class "
-                           "instance"));
-  
+    BT.reset(new APIMisuse(
+        this, "message incorrectly sent to class instead of class instance"));
+
     ASTContext &Ctx = C.getASTContext();
     releaseS = GetNullarySelector("release", Ctx);
     retainS = GetNullarySelector("retain", Ctx);
@@ -708,7 +709,8 @@ VariadicMethodTypeChecker::isVariadicMes
 void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                     CheckerContext &C) const {
   if (!BT) {
-    BT.reset(new APIMisuse("Arguments passed to variadic method aren't all "
+    BT.reset(new APIMisuse(this,
+                           "Arguments passed to variadic method aren't all "
                            "Objective-C pointer types"));
 
     ASTContext &Ctx = C.getASTContext();
@@ -1263,6 +1265,7 @@ void ento::registerObjCLoopChecker(Check
   mgr.registerChecker<ObjCLoopChecker>();
 }
 
-void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
+void
+ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
   mgr.registerChecker<ObjCNonNilReturnValueChecker>();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp Tue Feb 11 15:49:21 2014
@@ -34,7 +34,7 @@ void BoolAssignmentChecker::emitReport(P
                                        CheckerContext &C) const {
   if (ExplodedNode *N = C.addTransition(state)) {
     if (!BT)
-      BT.reset(new BuiltinBug("Assignment of a non-Boolean value"));    
+      BT.reset(new BuiltinBug(this, "Assignment of a non-Boolean value"));
     C.emitReport(new BugReport(*BT, BT->getDescription(), N));
   }
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Tue Feb 11 15:49:21 2014
@@ -51,6 +51,11 @@ public:
     DefaultBool CheckCStringOutOfBounds;
     DefaultBool CheckCStringBufferOverlap;
     DefaultBool CheckCStringNotNullTerm;
+
+    CheckName CheckNameCStringNullArg;
+    CheckName CheckNameCStringOutOfBounds;
+    CheckName CheckNameCStringBufferOverlap;
+    CheckName CheckNameCStringNotNullTerm;
   };
 
   CStringChecksFilter Filter;
@@ -232,8 +237,9 @@ ProgramStateRef CStringChecker::checkNon
       return NULL;
 
     if (!BT_Null)
-      BT_Null.reset(new BuiltinBug(categories::UnixAPI,
-        "Null pointer argument in call to byte string function"));
+      BT_Null.reset(new BuiltinBug(
+          Filter.CheckNameCStringNullArg, categories::UnixAPI,
+          "Null pointer argument in call to byte string function"));
 
     SmallString<80> buf;
     llvm::raw_svector_ostream os(buf);
@@ -294,8 +300,9 @@ ProgramStateRef CStringChecker::CheckLoc
       return NULL;
 
     if (!BT_Bounds) {
-      BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
-        "Byte string function accesses out-of-bound array element"));
+      BT_Bounds.reset(new BuiltinBug(
+          Filter.CheckNameCStringOutOfBounds, "Out-of-bound array access",
+          "Byte string function accesses out-of-bound array element"));
     }
     BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds.get());
 
@@ -526,7 +533,8 @@ void CStringChecker::emitOverlapBug(Chec
     return;
 
   if (!BT_Overlap)
-    BT_Overlap.reset(new BugType(categories::UnixAPI, "Improper arguments"));
+    BT_Overlap.reset(new BugType(Filter.CheckNameCStringBufferOverlap,
+                                 categories::UnixAPI, "Improper arguments"));
 
   // Generate a report for this bug.
   BugReport *report = 
@@ -586,8 +594,9 @@ ProgramStateRef CStringChecker::checkAdd
         return NULL;
 
       if (!BT_AdditionOverflow)
-        BT_AdditionOverflow.reset(new BuiltinBug("API",
-          "Sum of expressions causes overflow"));
+        BT_AdditionOverflow.reset(
+            new BuiltinBug(Filter.CheckNameCStringOutOfBounds, "API",
+                           "Sum of expressions causes overflow"));
 
       // This isn't a great error message, but this should never occur in real
       // code anyway -- you'd have to create a buffer longer than a size_t can
@@ -703,8 +712,9 @@ SVal CStringChecker::getCStringLength(Ch
 
       if (ExplodedNode *N = C.addTransition(state)) {
         if (!BT_NotCString)
-          BT_NotCString.reset(new BuiltinBug(categories::UnixAPI,
-            "Argument is not a null-terminated string."));
+          BT_NotCString.reset(new BuiltinBug(
+              Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
+              "Argument is not a null-terminated string."));
 
         SmallString<120> buf;
         llvm::raw_svector_ostream os(buf);
@@ -714,8 +724,7 @@ SVal CStringChecker::getCStringLength(Ch
            << "', which is not a null-terminated string";
 
         // Generate a report for this bug.
-        BugReport *report = new BugReport(*BT_NotCString,
-                                                          os.str(), N);
+        BugReport *report = new BugReport(*BT_NotCString, os.str(), N);
 
         report->addRange(Ex->getSourceRange());
         C.emitReport(report);        
@@ -763,8 +772,9 @@ SVal CStringChecker::getCStringLength(Ch
 
     if (ExplodedNode *N = C.addTransition(state)) {
       if (!BT_NotCString)
-        BT_NotCString.reset(new BuiltinBug(categories::UnixAPI,
-          "Argument is not a null-terminated string."));
+        BT_NotCString.reset(new BuiltinBug(
+            Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
+            "Argument is not a null-terminated string."));
 
       SmallString<120> buf;
       llvm::raw_svector_ostream os(buf);
@@ -2057,10 +2067,12 @@ void CStringChecker::checkDeadSymbols(Sy
   C.addTransition(state);
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  mgr.registerChecker<CStringChecker>()->Filter.Check##name = true; \
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    CStringChecker *checker = mgr.registerChecker<CStringChecker>();           \
+    checker->Filter.Check##name = true;                                        \
+    checker->Filter.CheckName##name = mgr.getCurrentCheckName();               \
+  }
 
 REGISTER_CHECKER(CStringNullArg)
 REGISTER_CHECKER(CStringOutOfBounds)

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp Tue Feb 11 15:49:21 2014
@@ -31,6 +31,7 @@ using namespace ento;
 
 namespace {
 class WalkAST: public StmtVisitor<WalkAST> {
+  const CheckerBase *Checker;
   BugReporter &BR;
   AnalysisDeclContext* AC;
 
@@ -81,9 +82,8 @@ class WalkAST: public StmtVisitor<WalkAS
   bool containsBadStrncatPattern(const CallExpr *CE);
 
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext* ac) :
-      BR(br), AC(ac) {
-  }
+  WalkAST(const CheckerBase *checker, BugReporter &br, AnalysisDeclContext *ac)
+      : Checker(checker), BR(br), AC(ac) {}
 
   // Statement visitor methods.
   void VisitChildren(Stmt *S);
@@ -157,8 +157,9 @@ void WalkAST::VisitCallExpr(CallExpr *CE
         os << "U";
       os << "se a safer 'strlcat' API";
 
-      BR.EmitBasicReport(FD, "Anti-pattern in the argument", "C String API",
-                         os.str(), Loc, LenArg->getSourceRange());
+      BR.EmitBasicReport(FD, Checker, "Anti-pattern in the argument",
+                         "C String API", os.str(), Loc,
+                         LenArg->getSourceRange());
     }
   }
 
@@ -179,7 +180,7 @@ public:
 
   void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
       BugReporter &BR) const {
-    WalkAST walker(BR, Mgr.getAnalysisDeclContext(D));
+    WalkAST walker(this, BR, Mgr.getAnalysisDeclContext(D));
     walker.Visit(D->getBody());
   }
 };

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Tue Feb 11 15:49:21 2014
@@ -52,10 +52,10 @@ public:
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
 
 private:
-  static bool PreVisitProcessArg(CheckerContext &C, SVal V,
-                                 SourceRange argRange, const Expr *argEx,
-                                 bool IsFirstArgument, bool checkUninitFields,
-                                 const CallEvent &Call, OwningPtr<BugType> &BT);
+  bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange argRange,
+                          const Expr *argEx, bool IsFirstArgument,
+                          bool checkUninitFields, const CallEvent &Call,
+                          OwningPtr<BugType> &BT) const;
 
   static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
   void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
@@ -65,9 +65,9 @@ private:
                          ProgramStateRef state,
                          const ObjCMethodCall &msg) const;
 
-  static void LazyInit_BT(const char *desc, OwningPtr<BugType> &BT) {
+  void LazyInit_BT(const char *desc, OwningPtr<BugType> &BT) const {
     if (!BT)
-      BT.reset(new BuiltinBug(desc));
+      BT.reset(new BuiltinBug(this, desc));
   }
 };
 } // end anonymous namespace
@@ -119,7 +119,7 @@ bool CallAndMessageChecker::PreVisitProc
                                                bool IsFirstArgument,
                                                bool checkUninitFields,
                                                const CallEvent &Call,
-                                               OwningPtr<BugType> &BT) {
+                                               OwningPtr<BugType> &BT) const {
   if (V.isUndef()) {
     if (ExplodedNode *N = C.generateSink()) {
       LazyInit_BT("Uninitialized argument value", BT);
@@ -234,8 +234,8 @@ void CallAndMessageChecker::checkPreStmt
 
   if (L.isUndef()) {
     if (!BT_call_undef)
-      BT_call_undef.reset(new BuiltinBug("Called function pointer is an "
-                                         "uninitalized pointer value"));
+      BT_call_undef.reset(new BuiltinBug(
+          this, "Called function pointer is an uninitalized pointer value"));
     emitBadCall(BT_call_undef.get(), C, Callee);
     return;
   }
@@ -246,8 +246,8 @@ void CallAndMessageChecker::checkPreStmt
 
   if (StNull && !StNonNull) {
     if (!BT_call_null)
-      BT_call_null.reset(
-        new BuiltinBug("Called function pointer is null (null dereference)"));
+      BT_call_null.reset(new BuiltinBug(
+          this, "Called function pointer is null (null dereference)"));
     emitBadCall(BT_call_null.get(), C, Callee);
     return;
   }
@@ -265,7 +265,8 @@ void CallAndMessageChecker::checkPreStmt
     if (!N)
       return;
     if (!BT_cxx_delete_undef)
-      BT_cxx_delete_undef.reset(new BuiltinBug("Uninitialized argument value"));
+      BT_cxx_delete_undef.reset(
+          new BuiltinBug(this, "Uninitialized argument value"));
     if (DE->isArrayFormAsWritten())
       Desc = "Argument to 'delete[]' is uninitialized";
     else
@@ -289,8 +290,8 @@ void CallAndMessageChecker::checkPreCall
     SVal V = CC->getCXXThisVal();
     if (V.isUndef()) {
       if (!BT_cxx_call_undef)
-        BT_cxx_call_undef.reset(new BuiltinBug("Called C++ object pointer is "
-                                               "uninitialized"));
+        BT_cxx_call_undef.reset(
+            new BuiltinBug(this, "Called C++ object pointer is uninitialized"));
       emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
       return;
     }
@@ -301,8 +302,8 @@ void CallAndMessageChecker::checkPreCall
 
     if (StNull && !StNonNull) {
       if (!BT_cxx_call_null)
-        BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
-                                              "is null"));
+        BT_cxx_call_null.reset(
+            new BuiltinBug(this, "Called C++ object pointer is null"));
       emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
       return;
     }
@@ -365,22 +366,21 @@ void CallAndMessageChecker::checkPreObjC
       switch (msg.getMessageKind()) {
       case OCM_Message:
         if (!BT_msg_undef)
-          BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
+          BT_msg_undef.reset(new BuiltinBug(this,
+                                            "Receiver in message expression "
                                             "is an uninitialized value"));
         BT = BT_msg_undef.get();
         break;
       case OCM_PropertyAccess:
         if (!BT_objc_prop_undef)
-          BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
-                                                  "uninitialized object "
-                                                  "pointer"));
+          BT_objc_prop_undef.reset(new BuiltinBug(
+              this, "Property access on an uninitialized object pointer"));
         BT = BT_objc_prop_undef.get();
         break;
       case OCM_Subscript:
         if (!BT_objc_subscript_undef)
-          BT_objc_subscript_undef.reset(new BuiltinBug("Subscript access on an "
-                                                       "uninitialized object "
-                                                       "pointer"));
+          BT_objc_subscript_undef.reset(new BuiltinBug(
+              this, "Subscript access on an uninitialized object pointer"));
         BT = BT_objc_subscript_undef.get();
         break;
       }
@@ -418,7 +418,7 @@ void CallAndMessageChecker::emitNilRecei
 
   if (!BT_msg_ret)
     BT_msg_ret.reset(
-      new BuiltinBug("Receiver in message expression is 'nil'"));
+        new BuiltinBug(this, "Receiver in message expression is 'nil'"));
 
   const ObjCMessageExpr *ME = msg.getOriginExpr();
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp Tue Feb 11 15:49:21 2014
@@ -69,9 +69,10 @@ void CastSizeChecker::checkPreStmt(const
   if (regionSize % typeSize != 0) {
     if (ExplodedNode *errorNode = C.generateSink()) {
       if (!BT)
-        BT.reset(new BuiltinBug("Cast region with wrong size.",
-                            "Cast a region whose size is not a multiple of the"
-                            " destination type size."));
+        BT.reset(
+            new BuiltinBug(this, "Cast region with wrong size.",
+                           "Cast a region whose size is not a multiple of the"
+                           " destination type size."));
       BugReport *R = new BugReport(*BT, BT->getDescription(),
                                                errorNode);
       R->addRange(CE->getSourceRange());
@@ -80,7 +81,6 @@ void CastSizeChecker::checkPreStmt(const
   }
 }
 
-
 void ento::registerCastSizeChecker(CheckerManager &mgr) {
-  mgr.registerChecker<CastSizeChecker>();  
+  mgr.registerChecker<CastSizeChecker>();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp Tue Feb 11 15:49:21 2014
@@ -58,10 +58,11 @@ void CastToStructChecker::checkPreStmt(c
   if (!OrigPointeeTy->isRecordType()) {
     if (ExplodedNode *N = C.addTransition()) {
       if (!BT)
-        BT.reset(new BuiltinBug("Cast from non-struct type to struct type",
-                            "Casting a non-structure type to a structure type "
-                            "and accessing a field can lead to memory access "
-                            "errors or data corruption."));
+        BT.reset(
+            new BuiltinBug(this, "Cast from non-struct type to struct type",
+                           "Casting a non-structure type to a structure type "
+                           "and accessing a field can lead to memory access "
+                           "errors or data corruption."));
       BugReport *R = new BugReport(*BT,BT->getDescription(), N);
       R->addRange(CE->getSourceRange());
       C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Tue Feb 11 15:49:21 2014
@@ -97,8 +97,9 @@ static bool scan_ivar_release(Stmt *S, O
   return false;
 }
 
-static void checkObjCDealloc(const ObjCImplementationDecl *D,
-                             const LangOptions& LOpts, BugReporter& BR) {
+static void checkObjCDealloc(const CheckerBase *Checker,
+                             const ObjCImplementationDecl *D,
+                             const LangOptions &LOpts, BugReporter &BR) {
 
   assert (LOpts.getGC() != LangOptions::GCOnly);
 
@@ -180,7 +181,7 @@ static void checkObjCDealloc(const ObjCI
     llvm::raw_string_ostream os(buf);
     os << "Objective-C class '" << *D << "' lacks a 'dealloc' instance method";
 
-    BR.EmitBasicReport(D, name, categories::CoreFoundationObjectiveC,
+    BR.EmitBasicReport(D, Checker, name, categories::CoreFoundationObjectiveC,
                        os.str(), DLoc);
     return;
   }
@@ -198,7 +199,7 @@ static void checkObjCDealloc(const ObjCI
        << "' does not send a 'dealloc' message to its super class"
            " (missing [super dealloc])";
 
-    BR.EmitBasicReport(MD, name, categories::CoreFoundationObjectiveC,
+    BR.EmitBasicReport(MD, Checker, name, categories::CoreFoundationObjectiveC,
                        os.str(), DLoc);
     return;
   }
@@ -264,8 +265,8 @@ static void checkObjCDealloc(const ObjCI
       PathDiagnosticLocation SDLoc =
         PathDiagnosticLocation::createBegin(*I, BR.getSourceManager());
 
-      BR.EmitBasicReport(MD, name, categories::CoreFoundationObjectiveC,
-                         os.str(), SDLoc);
+      BR.EmitBasicReport(MD, Checker, name,
+                         categories::CoreFoundationObjectiveC, os.str(), SDLoc);
     }
   }
 }
@@ -282,7 +283,8 @@ public:
                     BugReporter &BR) const {
     if (mgr.getLangOpts().getGC() == LangOptions::GCOnly)
       return;
-    checkObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOpts(), BR);
+    checkObjCDealloc(this, cast<ObjCImplementationDecl>(D), mgr.getLangOpts(),
+                     BR);
   }
 };
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp Tue Feb 11 15:49:21 2014
@@ -40,7 +40,8 @@ static bool AreTypesCompatible(QualType
 static void CompareReturnTypes(const ObjCMethodDecl *MethDerived,
                                const ObjCMethodDecl *MethAncestor,
                                BugReporter &BR, ASTContext &Ctx,
-                               const ObjCImplementationDecl *ID) {
+                               const ObjCImplementationDecl *ID,
+                               const CheckerBase *Checker) {
 
   QualType ResDerived = MethDerived->getReturnType();
   QualType ResAncestor = MethAncestor->getReturnType();
@@ -69,15 +70,15 @@ static void CompareReturnTypes(const Obj
       PathDiagnosticLocation::createBegin(MethDerived,
                                           BR.getSourceManager());
 
-    BR.EmitBasicReport(MethDerived,
-                       "Incompatible instance method return type",
-                       categories::CoreFoundationObjectiveC,
-                       os.str(), MethDLoc);
+    BR.EmitBasicReport(
+        MethDerived, Checker, "Incompatible instance method return type",
+        categories::CoreFoundationObjectiveC, os.str(), MethDLoc);
   }
 }
 
 static void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
-                                       BugReporter& BR) {
+                                       BugReporter &BR,
+                                       const CheckerBase *Checker) {
 
   const ObjCInterfaceDecl *D = ID->getClassInterface();
   const ObjCInterfaceDecl *C = D->getSuperClass();
@@ -118,7 +119,7 @@ static void CheckObjCInstMethSignature(c
       ObjCMethodDecl *MethDerived = MI->second;
       MI->second = 0;
 
-      CompareReturnTypes(MethDerived, M, BR, Ctx, ID);
+      CompareReturnTypes(MethDerived, M, BR, Ctx, ID, Checker);
     }
 
     C = C->getSuperClass();
@@ -135,7 +136,7 @@ class ObjCMethSigsChecker : public Check
 public:
   void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    CheckObjCInstMethSignature(D, BR);
+    CheckObjCInstMethSignature(D, BR, this);
   }
 };
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp Tue Feb 11 15:49:21 2014
@@ -46,8 +46,18 @@ struct ChecksFilter {
   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 @@ void WalkAST::checkLoopConditionForFloat
 
   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 @@ void WalkAST::checkCall_gets(const CallE
   // 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 @@ void WalkAST::checkCall_getpw(const Call
   // 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 @@ void WalkAST::checkCall_mktemp(const Cal
   // 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 @@ void WalkAST::checkCall_mkstemp(const Ca
     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 @@ void WalkAST::checkCall_strcpy(const Cal
   // 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 @@ void WalkAST::checkCall_strcat(const Cal
   // 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 @@ void WalkAST::checkCall_rand(const CallE
 
   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 @@ void WalkAST::checkCall_random(const Cal
   // 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 @@ void WalkAST::checkCall_vfork(const Call
   // 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 @@ void WalkAST::checkUncheckedReturnValue(
 
   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 @@ public:
 };
 }
 
-#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)

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp Tue Feb 11 15:49:21 2014
@@ -24,10 +24,12 @@ using namespace ento;
 namespace {
 class WalkAST : public StmtVisitor<WalkAST> {
   BugReporter &BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext* AC;
 
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext* ac) : BR(br), AC(ac) {}
+  WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac)
+      : BR(br), Checker(checker), AC(ac) {}
   void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
   void VisitStmt(Stmt *S) { VisitChildren(S); }
   void VisitChildren(Stmt *S);
@@ -62,7 +64,7 @@ void WalkAST::VisitUnaryExprOrTypeTraitE
 
     PathDiagnosticLocation ELoc =
       PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC);
-    BR.EmitBasicReport(AC->getDecl(),
+    BR.EmitBasicReport(AC->getDecl(), Checker,
                        "Potential unintended use of sizeof() on pointer type",
                        categories::LogicError,
                        "The code calls sizeof() on a pointer type. "
@@ -80,7 +82,7 @@ class SizeofPointerChecker : public Chec
 public:
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                         BugReporter &BR) const {
-    WalkAST walker(BR, mgr.getAnalysisDeclContext(D));
+    WalkAST walker(BR, this, mgr.getAnalysisDeclContext(D));
     walker.Visit(D->getBody());
   }
 };

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp Tue Feb 11 15:49:21 2014
@@ -142,9 +142,9 @@ void ChrootChecker::checkPreStmt(const C
     if (isRootChanged((intptr_t) *k))
       if (ExplodedNode *N = C.addTransition()) {
         if (!BT_BreakJail)
-          BT_BreakJail.reset(new BuiltinBug("Break out of jail",
-                                        "No call of chdir(\"/\") immediately "
-                                        "after chroot"));
+          BT_BreakJail.reset(new BuiltinBug(
+              this, "Break out of jail", "No call of chdir(\"/\") immediately "
+                                         "after chroot"));
         BugReport *R = new BugReport(*BT_BreakJail, 
                                      BT_BreakJail->getDescription(), N);
         C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp Tue Feb 11 15:49:21 2014
@@ -124,6 +124,7 @@ class DeadStoreObs : public LiveVariable
   const CFG &cfg;
   ASTContext &Ctx;
   BugReporter& BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext* AC;
   ParentMap& Parents;
   llvm::SmallPtrSet<const VarDecl*, 20> Escaped;
@@ -134,11 +135,12 @@ class DeadStoreObs : public LiveVariable
   enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
 
 public:
-  DeadStoreObs(const CFG &cfg, ASTContext &ctx,
-               BugReporter& br, AnalysisDeclContext* ac, ParentMap& parents,
-               llvm::SmallPtrSet<const VarDecl*, 20> &escaped)
-    : cfg(cfg), Ctx(ctx), BR(br), AC(ac), Parents(parents),
-      Escaped(escaped), currentBlock(0) {}
+  DeadStoreObs(const CFG &cfg, ASTContext &ctx, BugReporter &br,
+               const CheckerBase *checker, AnalysisDeclContext *ac,
+               ParentMap &parents,
+               llvm::SmallPtrSet<const VarDecl *, 20> &escaped)
+      : cfg(cfg), Ctx(ctx), BR(br), Checker(checker), AC(ac), Parents(parents),
+        Escaped(escaped), currentBlock(0) {}
 
   virtual ~DeadStoreObs() {}
 
@@ -199,7 +201,8 @@ public:
         return;
     }
 
-    BR.EmitBasicReport(AC->getDecl(), BugType, "Dead store", os.str(), L, R);
+    BR.EmitBasicReport(AC->getDecl(), Checker, BugType, "Dead store", os.str(),
+                       L, R);
   }
 
   void CheckVarDecl(const VarDecl *VD, const Expr *Ex, const Expr *Val,
@@ -439,7 +442,7 @@ public:
       ParentMap &pmap = mgr.getParentMap(D);
       FindEscaped FS;
       cfg.VisitBlockStmts(FS);
-      DeadStoreObs A(cfg, BR.getContext(), BR, AC, pmap, FS.Escaped);
+      DeadStoreObs A(cfg, BR.getContext(), BR, this, AC, pmap, FS.Escaped);
       L->runOnAllBlocks(A);
     }
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp Tue Feb 11 15:49:21 2014
@@ -97,7 +97,7 @@ void DereferenceChecker::reportBug(Progr
   // We know that 'location' cannot be non-null.  This is what
   // we call an "explicit" null dereference.
   if (!BT_null)
-    BT_null.reset(new BuiltinBug("Dereference of null pointer"));
+    BT_null.reset(new BuiltinBug(this, "Dereference of null pointer"));
 
   SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
@@ -180,7 +180,8 @@ void DereferenceChecker::checkLocation(S
   if (l.isUndef()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_undef)
-        BT_undef.reset(new BuiltinBug("Dereference of undefined pointer value"));
+        BT_undef.reset(
+            new BuiltinBug(this, "Dereference of undefined pointer value"));
 
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp Tue Feb 11 15:49:21 2014
@@ -63,13 +63,15 @@ class DirectIvarAssignment :
     const ObjCMethodDecl *MD;
     const ObjCInterfaceDecl *InterfD;
     BugReporter &BR;
+    const CheckerBase *Checker;
     LocationOrAnalysisDeclContext DCtx;
 
   public:
     MethodCrawler(const IvarToPropertyMapTy &InMap, const ObjCMethodDecl *InMD,
-        const ObjCInterfaceDecl *InID,
-        BugReporter &InBR, AnalysisDeclContext *InDCtx)
-    : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR), DCtx(InDCtx) {}
+                  const ObjCInterfaceDecl *InID, BugReporter &InBR,
+                  const CheckerBase *Checker, AnalysisDeclContext *InDCtx)
+        : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR),
+          Checker(Checker), DCtx(InDCtx) {}
 
     void VisitStmt(const Stmt *S) { VisitChildren(S); }
 
@@ -152,7 +154,8 @@ void DirectIvarAssignment::checkASTDecl(
     const Stmt *Body = M->getBody();
     assert(Body);
 
-    MethodCrawler MC(IvarToPropMap, M->getCanonicalDecl(), InterD, BR, DCtx);
+    MethodCrawler MC(IvarToPropMap, M->getCanonicalDecl(), InterD, BR, this,
+                     DCtx);
     MC.VisitStmt(Body);
   }
 }
@@ -204,13 +207,11 @@ void DirectIvarAssignment::MethodCrawler
       if (GetterMethod && GetterMethod->getCanonicalDecl() == MD)
         return;
 
-      BR.EmitBasicReport(MD,
-          "Property access",
-          categories::CoreFoundationObjectiveC,
+      BR.EmitBasicReport(
+          MD, Checker, "Property access", categories::CoreFoundationObjectiveC,
           "Direct assignment to an instance variable backing a property; "
-          "use the setter instead", PathDiagnosticLocation(IvarRef,
-                                                          BR.getSourceManager(),
-                                                          DCtx));
+          "use the setter instead",
+          PathDiagnosticLocation(IvarRef, BR.getSourceManager(), DCtx));
     }
   }
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp Tue Feb 11 15:49:21 2014
@@ -37,7 +37,7 @@ void DivZeroChecker::reportBug(const cha
                                CheckerContext &C) const {
   if (ExplodedNode *N = C.generateSink(StateZero)) {
     if (!BT)
-      BT.reset(new BuiltinBug("Division by zero"));
+      BT.reset(new BuiltinBug(this, "Division by zero"));
 
     BugReport *R = new BugReport(*BT, Msg, N);
     bugreporter::trackNullOrUndefValue(N, bugreporter::GetDenomExpr(N), *R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp Tue Feb 11 15:49:21 2014
@@ -95,7 +95,7 @@ void ExprInspectionChecker::analyzerEval
     return;
 
   if (!BT)
-    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+    BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
   BugReport *R = new BugReport(*BT, getArgumentValueString(CE, C), N);
   C.emitReport(R);
@@ -106,7 +106,7 @@ void ExprInspectionChecker::analyzerWarn
   ExplodedNode *N = C.getPredecessor();
 
   if (!BT)
-    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+    BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
   BugReport *R = new BugReport(*BT, "REACHABLE", N);
   C.emitReport(R);
@@ -126,7 +126,7 @@ void ExprInspectionChecker::analyzerChec
     return;
 
   if (!BT)
-    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+    BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
   BugReport *R = new BugReport(*BT, getArgumentValueString(CE, C), N);
   C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp Tue Feb 11 15:49:21 2014
@@ -52,10 +52,11 @@ void FixedAddressChecker::checkPreStmt(c
 
   if (ExplodedNode *N = C.addTransition()) {
     if (!BT)
-      BT.reset(new BuiltinBug("Use fixed address", 
-                          "Using a fixed address is not portable because that "
-                          "address will probably not be valid in all "
-                          "environments or platforms."));
+      BT.reset(
+          new BuiltinBug(this, "Use fixed address",
+                         "Using a fixed address is not portable because that "
+                         "address will probably not be valid in all "
+                         "environments or platforms."));
     BugReport *R = new BugReport(*BT, BT->getDescription(), N);
     R->addRange(B->getRHS()->getSourceRange());
     C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Tue Feb 11 15:49:21 2014
@@ -46,7 +46,7 @@ private:
   mutable OwningPtr<BugType> BT;
   inline void initBugType() const {
     if (!BT)
-      BT.reset(new BugType("Use of Untrusted Data", "Untrusted Data"));
+      BT.reset(new BugType(this, "Use of Untrusted Data", "Untrusted Data"));
   }
 
   /// \brief Catch taint related bugs. Check if tainted data is passed to a

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp Tue Feb 11 15:49:21 2014
@@ -36,8 +36,10 @@ namespace {
 class FindIdenticalExprVisitor
     : public RecursiveASTVisitor<FindIdenticalExprVisitor> {
 public:
-  explicit FindIdenticalExprVisitor(BugReporter &B, AnalysisDeclContext *A)
-      : BR(B), AC(A) {}
+  explicit FindIdenticalExprVisitor(BugReporter &B,
+                                    const CheckerBase *Checker,
+                                    AnalysisDeclContext *A)
+      : BR(B), Checker(Checker), AC(A) {}
   // FindIdenticalExprVisitor only visits nodes
   // that are binary operators or conditional operators.
   bool VisitBinaryOperator(const BinaryOperator *B);
@@ -45,6 +47,7 @@ public:
 
 private:
   BugReporter &BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext *AC;
 };
 } // end anonymous namespace
@@ -112,7 +115,8 @@ bool FindIdenticalExprVisitor::VisitBina
       Message = "comparison of identical expressions always evaluates to true";
     else
       Message = "comparison of identical expressions always evaluates to false";
-    BR.EmitBasicReport(AC->getDecl(), "Compare of identical expressions",
+    BR.EmitBasicReport(AC->getDecl(), Checker,
+                       "Compare of identical expressions",
                        categories::LogicError, Message, ELoc);
   }
   // We want to visit ALL nodes (subexpressions of binary comparison
@@ -137,7 +141,8 @@ bool FindIdenticalExprVisitor::VisitCond
     Sr[0] = C->getTrueExpr()->getSourceRange();
     Sr[1] = C->getFalseExpr()->getSourceRange();
     BR.EmitBasicReport(
-        AC->getDecl(), "Identical expressions in conditional expression",
+        AC->getDecl(), Checker,
+        "Identical expressions in conditional expression",
         categories::LogicError,
         "identical expressions on both sides of ':' in conditional expression",
         ELoc, Sr);
@@ -245,7 +250,7 @@ class FindIdenticalExprChecker : public
 public:
   void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
                         BugReporter &BR) const {
-    FindIdenticalExprVisitor Visitor(BR, Mgr.getAnalysisDeclContext(D));
+    FindIdenticalExprVisitor Visitor(BR, this, Mgr.getAnalysisDeclContext(D));
     Visitor.TraverseDecl(const_cast<Decl *>(D));
   }
 };

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp Tue Feb 11 15:49:21 2014
@@ -49,6 +49,9 @@ struct ChecksFilter {
   DefaultBool check_MissingInvalidationMethod;
   /// Check that all ivars are invalidated.
   DefaultBool check_InstanceVariableInvalidation;
+
+  CheckName checkName_MissingInvalidationMethod;
+  CheckName checkName_InstanceVariableInvalidation;
 };
 
 class IvarInvalidationCheckerImpl {
@@ -200,7 +203,8 @@ class IvarInvalidationCheckerImpl {
                         const ObjCIvarDecl *IvarDecl,
                         const IvarToPropMapTy &IvarToPopertyMap);
 
-  void reportNoInvalidationMethod(const ObjCIvarDecl *FirstIvarDecl,
+  void reportNoInvalidationMethod(CheckName CheckName,
+                                  const ObjCIvarDecl *FirstIvarDecl,
                                   const IvarToPropMapTy &IvarToPopertyMap,
                                   const ObjCInterfaceDecl *InterfaceD,
                                   bool MissingDeclaration) const;
@@ -476,7 +480,8 @@ visit(const ObjCImplementationDecl *Impl
   // Report an error in case none of the invalidation methods are declared.
   if (!Info.needsInvalidation() && !PartialInfo.needsInvalidation()) {
     if (Filter.check_MissingInvalidationMethod)
-      reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
+      reportNoInvalidationMethod(Filter.checkName_MissingInvalidationMethod,
+                                 FirstIvarDecl, IvarToPopertyMap, InterfaceD,
                                  /*MissingDeclaration*/ true);
     // If there are no invalidation methods, there is no ivar validation work
     // to be done.
@@ -532,17 +537,17 @@ visit(const ObjCImplementationDecl *Impl
         reportIvarNeedsInvalidation(I->first, IvarToPopertyMap, 0);
     } else {
       // Otherwise, no invalidation methods were implemented.
-      reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
+      reportNoInvalidationMethod(Filter.checkName_InstanceVariableInvalidation,
+                                 FirstIvarDecl, IvarToPopertyMap, InterfaceD,
                                  /*MissingDeclaration*/ false);
     }
   }
 }
 
-void IvarInvalidationCheckerImpl::
-reportNoInvalidationMethod(const ObjCIvarDecl *FirstIvarDecl,
-                           const IvarToPropMapTy &IvarToPopertyMap,
-                           const ObjCInterfaceDecl *InterfaceD,
-                           bool MissingDeclaration) const {
+void IvarInvalidationCheckerImpl::reportNoInvalidationMethod(
+    CheckName CheckName, const ObjCIvarDecl *FirstIvarDecl,
+    const IvarToPropMapTy &IvarToPopertyMap,
+    const ObjCInterfaceDecl *InterfaceD, bool MissingDeclaration) const {
   SmallString<128> sbuf;
   llvm::raw_svector_ostream os(sbuf);
   assert(FirstIvarDecl);
@@ -557,7 +562,7 @@ reportNoInvalidationMethod(const ObjCIva
   PathDiagnosticLocation IvarDecLocation =
     PathDiagnosticLocation::createBegin(FirstIvarDecl, BR.getSourceManager());
 
-  BR.EmitBasicReport(FirstIvarDecl, "Incomplete invalidation",
+  BR.EmitBasicReport(FirstIvarDecl, CheckName, "Incomplete invalidation",
                      categories::CoreFoundationObjectiveC, os.str(),
                      IvarDecLocation);
 }
@@ -575,15 +580,16 @@ reportIvarNeedsInvalidation(const ObjCIv
                            PathDiagnosticLocation::createEnd(MethodD->getBody(),
                            BR.getSourceManager(),
                            Mgr.getAnalysisDeclContext(MethodD));
-    BR.EmitBasicReport(MethodD, "Incomplete invalidation",
+    BR.EmitBasicReport(MethodD, Filter.checkName_InstanceVariableInvalidation,
+                       "Incomplete invalidation",
                        categories::CoreFoundationObjectiveC, os.str(),
                        MethodDecLocation);
   } else {
-    BR.EmitBasicReport(IvarD, "Incomplete invalidation",
-                       categories::CoreFoundationObjectiveC, os.str(),
-                       PathDiagnosticLocation::createBegin(IvarD,
-                                                        BR.getSourceManager()));
-                       
+    BR.EmitBasicReport(
+        IvarD, Filter.checkName_InstanceVariableInvalidation,
+        "Incomplete invalidation", categories::CoreFoundationObjectiveC,
+        os.str(),
+        PathDiagnosticLocation::createBegin(IvarD, BR.getSourceManager()));
   }
 }
 
@@ -750,10 +756,13 @@ public:
 };
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  mgr.registerChecker<IvarInvalidationChecker>()->Filter.check_##name = true;\
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    IvarInvalidationChecker *checker =                                         \
+        mgr.registerChecker<IvarInvalidationChecker>();                        \
+    checker->Filter.check_##name = true;                                       \
+    checker->Filter.checkName_##name = mgr.getCurrentCheckName();              \
+  }
 
 REGISTER_CHECKER(InstanceVariableInvalidation)
 REGISTER_CHECKER(MissingInvalidationMethod)

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp Tue Feb 11 15:49:21 2014
@@ -115,11 +115,14 @@ static bool IsSmallVector(QualType T) {
 
 namespace {
 class StringRefCheckerVisitor : public StmtVisitor<StringRefCheckerVisitor> {
-  BugReporter &BR;
   const Decl *DeclWithIssue;
+  BugReporter &BR;
+  const CheckerBase *Checker;
+
 public:
-  StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br)
-    : BR(br), DeclWithIssue(declWithIssue) {}
+  StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br,
+                          const CheckerBase *checker)
+      : DeclWithIssue(declWithIssue), BR(br), Checker(checker) {}
   void VisitChildren(Stmt *S) {
     for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ;
       I != E; ++I)
@@ -133,8 +136,9 @@ private:
 };
 } // end anonymous namespace
 
-static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR) {
-  StringRefCheckerVisitor walker(D, BR);
+static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR,
+                                            const CheckerBase *Checker) {
+  StringRefCheckerVisitor walker(D, BR, Checker);
   walker.Visit(D->getBody());
 }
 
@@ -179,7 +183,7 @@ void StringRefCheckerVisitor::VisitVarDe
                      "std::string that it outlives";
   PathDiagnosticLocation VDLoc =
     PathDiagnosticLocation::createBegin(VD, BR.getSourceManager());
-  BR.EmitBasicReport(DeclWithIssue, desc, "LLVM Conventions", desc,
+  BR.EmitBasicReport(DeclWithIssue, Checker, desc, "LLVM Conventions", desc,
                      VDLoc, Init->getSourceRange());
 }
 
@@ -216,22 +220,26 @@ class ASTFieldVisitor {
   SmallVector<FieldDecl*, 10> FieldChain;
   const CXXRecordDecl *Root;
   BugReporter &BR;
+  const CheckerBase *Checker;
+
 public:
-  ASTFieldVisitor(const CXXRecordDecl *root, BugReporter &br)
-    : Root(root), BR(br) {}
+  ASTFieldVisitor(const CXXRecordDecl *root, BugReporter &br,
+                  const CheckerBase *checker)
+      : Root(root), BR(br), Checker(checker) {}
 
   void Visit(FieldDecl *D);
   void ReportError(QualType T);
 };
 } // end anonymous namespace
 
-static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR) {
+static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR,
+                           const CheckerBase *Checker) {
   if (!IsPartOfAST(R))
     return;
 
   for (RecordDecl::field_iterator I = R->field_begin(), E = R->field_end();
        I != E; ++I) {
-    ASTFieldVisitor walker(R, BR);
+    ASTFieldVisitor walker(R, BR, Checker);
     walker.Visit(*I);
   }
 }
@@ -284,8 +292,8 @@ void ASTFieldVisitor::ReportError(QualTy
   // the class may be in the header file, for example).
   PathDiagnosticLocation L = PathDiagnosticLocation::createBegin(
                                FieldChain.front(), BR.getSourceManager());
-  BR.EmitBasicReport(Root, "AST node allocates heap memory", "LLVM Conventions",
-                     os.str(), L);
+  BR.EmitBasicReport(Root, Checker, "AST node allocates heap memory",
+                     "LLVM Conventions", os.str(), L);
 }
 
 //===----------------------------------------------------------------------===//
@@ -300,12 +308,12 @@ public:
   void checkASTDecl(const CXXRecordDecl *R, AnalysisManager& mgr,
                     BugReporter &BR) const {
     if (R->isCompleteDefinition())
-      CheckASTMemory(R, BR);
+      CheckASTMemory(R, BR, this);
   }
 
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                         BugReporter &BR) const {
-    CheckStringRefAssignedTemporary(D, BR);
+    CheckStringRefAssignedTemporary(D, BR, this);
   }
 };
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp Tue Feb 11 15:49:21 2014
@@ -91,7 +91,7 @@ private:
 
   inline void initBugType() const {
     if (!BT)
-      BT.reset(new BugType("Improper use of SecKeychain API",
+      BT.reset(new BugType(this, "Improper use of SecKeychain API",
                            "API Misuse (Apple)"));
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp Tue Feb 11 15:49:21 2014
@@ -67,7 +67,7 @@ void MacOSXAPIChecker::CheckDispatchOnce
     return;
 
   if (!BT_dispatchOnce)
-    BT_dispatchOnce.reset(new BugType("Improper use of 'dispatch_once'",
+    BT_dispatchOnce.reset(new BugType(this, "Improper use of 'dispatch_once'",
                                       "API Misuse (Apple)"));
 
   // Handle _dispatch_once.  In some versions of the OS X SDK we have the case

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Feb 11 15:49:21 2014
@@ -155,31 +155,23 @@ class MallocChecker : public Checker<che
                                      check::Location,
                                      eval::Assume>
 {
-  mutable OwningPtr<BugType> BT_DoubleFree;
-  mutable OwningPtr<BugType> BT_DoubleDelete;
-  mutable OwningPtr<BugType> BT_Leak;
-  mutable OwningPtr<BugType> BT_UseFree;
-  mutable OwningPtr<BugType> BT_BadFree;
-  mutable OwningPtr<BugType> BT_MismatchedDealloc;
-  mutable OwningPtr<BugType> BT_OffsetFree;
-  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
-                         *II_valloc, *II_reallocf, *II_strndup, *II_strdup;
-
 public:
   MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0),
                     II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {}
 
   /// In pessimistic mode, the checker assumes that it does not know which
   /// functions might free the memory.
-  struct ChecksFilter {
-    DefaultBool CMallocPessimistic;
-    DefaultBool CMallocOptimistic;
-    DefaultBool CNewDeleteChecker;
-    DefaultBool CNewDeleteLeaksChecker;
-    DefaultBool CMismatchedDeallocatorChecker;
+  enum CheckKind {
+    CK_MallocPessimistic,
+    CK_MallocOptimistic,
+    CK_NewDeleteChecker,
+    CK_NewDeleteLeaksChecker,
+    CK_MismatchedDeallocatorChecker,
+    CK_NumCheckKinds
   };
 
-  ChecksFilter Filter;
+  DefaultBool ChecksEnabled[CK_NumCheckKinds];
+  CheckName CheckNames[CK_NumCheckKinds];
 
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -207,6 +199,16 @@ public:
                   const char *NL, const char *Sep) const;
 
 private:
+  mutable OwningPtr<BugType> BT_DoubleFree[CK_NumCheckKinds];
+  mutable OwningPtr<BugType> BT_DoubleDelete;
+  mutable OwningPtr<BugType> BT_Leak[CK_NumCheckKinds];
+  mutable OwningPtr<BugType> BT_UseFree[CK_NumCheckKinds];
+  mutable OwningPtr<BugType> BT_BadFree[CK_NumCheckKinds];
+  mutable OwningPtr<BugType> BT_MismatchedDealloc;
+  mutable OwningPtr<BugType> BT_OffsetFree[CK_NumCheckKinds];
+  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
+                         *II_valloc, *II_reallocf, *II_strndup, *II_strdup;
+
   void initIdentifierInfo(ASTContext &C) const;
 
   /// \brief Determine family of a deallocation expression.
@@ -304,10 +306,12 @@ private:
 
   ///@{
   /// Tells if a given family/call/symbol is tracked by the current checker.
-  bool isTrackedByCurrentChecker(AllocationFamily Family) const;
-  bool isTrackedByCurrentChecker(CheckerContext &C,
-                                 const Stmt *AllocDeallocStmt) const;
-  bool isTrackedByCurrentChecker(CheckerContext &C, SymbolRef Sym) const;
+  /// Sets CheckKind to the kind of the checker responsible for this
+  /// family/call/symbol.
+  Optional<CheckKind> getCheckIfTracked(AllocationFamily Family) const;
+  Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
+                                        const Stmt *AllocDeallocStmt) const;
+  Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const;
   ///@}
   static bool SummarizeValue(raw_ostream &os, SVal V);
   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
@@ -507,7 +511,7 @@ bool MallocChecker::isAllocationFunction
       return true;
   }
 
-  if (Filter.CMallocOptimistic && FD->hasAttrs())
+  if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs())
     for (specific_attr_iterator<OwnershipAttr>
            i = FD->specific_attr_begin<OwnershipAttr>(),
            e = FD->specific_attr_end<OwnershipAttr>();
@@ -529,7 +533,7 @@ bool MallocChecker::isFreeFunction(const
       return true;
   }
 
-  if (Filter.CMallocOptimistic && FD->hasAttrs())
+  if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs())
     for (specific_attr_iterator<OwnershipAttr>
            i = FD->specific_attr_begin<OwnershipAttr>(),
            e = FD->specific_attr_end<OwnershipAttr>();
@@ -624,7 +628,8 @@ void MallocChecker::checkPostStmt(const
     }
   }
 
-  if (Filter.CMallocOptimistic || Filter.CMismatchedDeallocatorChecker) {
+  if (ChecksEnabled[CK_MallocOptimistic] ||
+      ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
     // Check all the attributes, if there are any.
     // There can be multiple of these attributes.
     if (FD->hasAttrs())
@@ -671,7 +676,7 @@ void MallocChecker::checkPostStmt(const
 void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, 
                                  CheckerContext &C) const {
 
-  if (!Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_NewDeleteChecker])
     if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
       checkUseAfterFree(Sym, C, DE->getArgument());
 
@@ -1092,18 +1097,23 @@ ProgramStateRef MallocChecker::FreeMemAu
                                  RefState::getReleased(Family, ParentExpr));
 }
 
-bool MallocChecker::isTrackedByCurrentChecker(AllocationFamily Family) const {
+Optional<MallocChecker::CheckKind>
+MallocChecker::getCheckIfTracked(AllocationFamily Family) const {
   switch (Family) {
   case AF_Malloc: {
-    if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic)
-      return false;
-    return true;
+    if (ChecksEnabled[CK_MallocOptimistic]) {
+      return CK_MallocOptimistic;
+    } else if (ChecksEnabled[CK_MallocPessimistic]) {
+      return CK_MallocPessimistic;
+    }
+    return Optional<MallocChecker::CheckKind>();
   }
   case AF_CXXNew:
   case AF_CXXNewArray: {
-    if (!Filter.CNewDeleteChecker)
-      return false;
-    return true;
+    if (ChecksEnabled[CK_NewDeleteChecker]) {
+      return CK_NewDeleteChecker;
+    }
+    return Optional<MallocChecker::CheckKind>();
   }
   case AF_None: {
     llvm_unreachable("no family");
@@ -1112,18 +1122,18 @@ bool MallocChecker::isTrackedByCurrentCh
   llvm_unreachable("unhandled family");
 }
 
-bool
-MallocChecker::isTrackedByCurrentChecker(CheckerContext &C, 
-                                         const Stmt *AllocDeallocStmt) const {
-  return isTrackedByCurrentChecker(getAllocationFamily(C, AllocDeallocStmt));
+Optional<MallocChecker::CheckKind>
+MallocChecker::getCheckIfTracked(CheckerContext &C,
+                                 const Stmt *AllocDeallocStmt) const {
+  return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt));
 }
 
-bool MallocChecker::isTrackedByCurrentChecker(CheckerContext &C,
-                                              SymbolRef Sym) const {
+Optional<MallocChecker::CheckKind>
+MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const {
 
   const RefState *RS = C.getState()->get<RegionState>(Sym);
   assert(RS);
-  return isTrackedByCurrentChecker(RS->getAllocationFamily());
+  return getCheckIfTracked(RS->getAllocationFamily());
 }
 
 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
@@ -1217,17 +1227,21 @@ void MallocChecker::ReportBadFree(Checke
                                   SourceRange Range, 
                                   const Expr *DeallocExpr) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, DeallocExpr))
+  Optional<MallocChecker::CheckKind> CheckKind =
+      getCheckIfTracked(C, DeallocExpr);
+  if (!CheckKind.hasValue())
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
-    if (!BT_BadFree)
-      BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
-    
+    if (!BT_BadFree[*CheckKind])
+      BT_BadFree[*CheckKind].reset(
+          new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error"));
+
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
 
@@ -1253,7 +1267,7 @@ void MallocChecker::ReportBadFree(Checke
       printExpectedAllocName(os, C, DeallocExpr);
     }
 
-    BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
+    BugReport *R = new BugReport(*BT_BadFree[*CheckKind], os.str(), N);
     R->markInteresting(MR);
     R->addRange(Range);
     C.emitReport(R);
@@ -1267,14 +1281,15 @@ void MallocChecker::ReportMismatchedDeal
                                             SymbolRef Sym, 
                                             bool OwnershipTransferred) const {
 
-  if (!Filter.CMismatchedDeallocatorChecker)
+  if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
     if (!BT_MismatchedDealloc)
-      BT_MismatchedDealloc.reset(new BugType("Bad deallocator",
-                                             "Memory Error"));
-    
+      BT_MismatchedDealloc.reset(
+          new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
+                      "Bad deallocator", "Memory Error"));
+
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
 
@@ -1318,19 +1333,23 @@ void MallocChecker::ReportOffsetFree(Che
                                      SourceRange Range, const Expr *DeallocExpr,
                                      const Expr *AllocExpr) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, AllocExpr))
+  Optional<MallocChecker::CheckKind> CheckKind =
+      getCheckIfTracked(C, AllocExpr);
+  if (!CheckKind.hasValue())
     return;
 
   ExplodedNode *N = C.generateSink();
   if (N == NULL)
     return;
 
-  if (!BT_OffsetFree)
-    BT_OffsetFree.reset(new BugType("Offset free", "Memory Error"));
+  if (!BT_OffsetFree[*CheckKind])
+    BT_OffsetFree[*CheckKind].reset(
+        new BugType(CheckNames[*CheckKind], "Offset free", "Memory Error"));
 
   SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
@@ -1361,7 +1380,7 @@ void MallocChecker::ReportOffsetFree(Che
   else
     os << "allocated memory";
 
-  BugReport *R = new BugReport(*BT_OffsetFree, os.str(), N);
+  BugReport *R = new BugReport(*BT_OffsetFree[*CheckKind], os.str(), N);
   R->markInteresting(MR->getBaseRegion());
   R->addRange(Range);
   C.emitReport(R);
@@ -1370,18 +1389,21 @@ void MallocChecker::ReportOffsetFree(Che
 void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
                                        SymbolRef Sym) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, Sym))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
+  if (!CheckKind.hasValue())
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
-    if (!BT_UseFree)
-      BT_UseFree.reset(new BugType("Use-after-free", "Memory Error"));
+    if (!BT_UseFree[*CheckKind])
+      BT_UseFree[*CheckKind].reset(new BugType(
+          CheckNames[*CheckKind], "Use-after-free", "Memory Error"));
 
-    BugReport *R = new BugReport(*BT_UseFree,
+    BugReport *R = new BugReport(*BT_UseFree[*CheckKind],
                                  "Use of memory after it is freed", N);
 
     R->markInteresting(Sym);
@@ -1395,21 +1417,25 @@ void MallocChecker::ReportDoubleFree(Che
                                      bool Released, SymbolRef Sym, 
                                      SymbolRef PrevSym) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, Sym))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
+  if (!CheckKind.hasValue())
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
-    if (!BT_DoubleFree)
-      BT_DoubleFree.reset(new BugType("Double free", "Memory Error"));
-
-    BugReport *R = new BugReport(*BT_DoubleFree,
-      (Released ? "Attempt to free released memory"
-                : "Attempt to free non-owned memory"),
-      N);
+    if (!BT_DoubleFree[*CheckKind])
+      BT_DoubleFree[*CheckKind].reset(
+          new BugType(CheckNames[*CheckKind], "Double free", "Memory Error"));
+
+    BugReport *R =
+        new BugReport(*BT_DoubleFree[*CheckKind],
+                      (Released ? "Attempt to free released memory"
+                                : "Attempt to free non-owned memory"),
+                      N);
     R->addRange(Range);
     R->markInteresting(Sym);
     if (PrevSym)
@@ -1421,15 +1447,18 @@ void MallocChecker::ReportDoubleFree(Che
 
 void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
 
-  if (!Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, Sym))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
+  if (!CheckKind.hasValue())
     return;
+  assert(*CheckKind == CK_NewDeleteChecker && "invalid check kind");
 
   if (ExplodedNode *N = C.generateSink()) {
     if (!BT_DoubleDelete)
-      BT_DoubleDelete.reset(new BugType("Double delete", "Memory Error"));
+      BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
+                                        "Double delete", "Memory Error"));
 
     BugReport *R = new BugReport(*BT_DoubleDelete,
                                  "Attempt to delete released memory", N);
@@ -1601,31 +1630,34 @@ MallocChecker::getAllocationSite(const E
 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
                                CheckerContext &C) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteLeaksChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteLeaksChecker])
     return;
 
   const RefState *RS = C.getState()->get<RegionState>(Sym);
   assert(RS && "cannot leak an untracked symbol");
   AllocationFamily Family = RS->getAllocationFamily();
-  if (!isTrackedByCurrentChecker(Family))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
+  if (!CheckKind.hasValue())
     return;
 
   // Special case for new and new[]; these are controlled by a separate checker
   // flag so that they can be selectively disabled.
   if (Family == AF_CXXNew || Family == AF_CXXNewArray)
-    if (!Filter.CNewDeleteLeaksChecker)
+    if (!ChecksEnabled[CK_NewDeleteLeaksChecker])
       return;
 
   assert(N);
-  if (!BT_Leak) {
-    BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
+  if (!BT_Leak[*CheckKind]) {
+    BT_Leak[*CheckKind].reset(
+        new BugType(CheckNames[*CheckKind], "Memory leak", "Memory Error"));
     // Leaks should not be reported if they are post-dominated by a sink:
     // (1) Sinks are higher importance bugs.
     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
     //     with __noreturn functions such as assert() or exit(). We choose not
     //     to report leaks on such paths.
-    BT_Leak->setSuppressOnSink(true);
+    BT_Leak[*CheckKind]->setSuppressOnSink(true);
   }
 
   // Most bug reports are cached at the location where they occurred.
@@ -1656,9 +1688,9 @@ void MallocChecker::reportLeak(SymbolRef
     os << "Potential memory leak";
   }
 
-  BugReport *R = new BugReport(*BT_Leak, os.str(), N, 
-                               LocUsedForUniqueing, 
-                               AllocNode->getLocationContext()->getDecl());
+  BugReport *R =
+      new BugReport(*BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
+                    AllocNode->getLocationContext()->getDecl());
   R->markInteresting(Sym);
   R->addVisitor(new MallocBugVisitor(Sym, true));
   C.emitReport(R);
@@ -1732,11 +1764,12 @@ void MallocChecker::checkPreCall(const C
     if (!FD)
       return;
 
-    if ((Filter.CMallocOptimistic || Filter.CMallocPessimistic) &&
+    if ((ChecksEnabled[CK_MallocOptimistic] ||
+         ChecksEnabled[CK_MallocPessimistic]) &&
         isFreeFunction(FD, C.getASTContext()))
       return;
 
-    if (Filter.CNewDeleteChecker &&
+    if (ChecksEnabled[CK_NewDeleteChecker] &&
         isStandardNewDelete(FD, C.getASTContext()))
       return;
   }
@@ -2230,17 +2263,26 @@ void MallocChecker::printState(raw_ostre
 
 void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
   registerCStringCheckerBasic(mgr);
-  mgr.registerChecker<MallocChecker>()->Filter.CNewDeleteLeaksChecker = true;
+  MallocChecker *checker = mgr.registerChecker<MallocChecker>();
+  checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
+  checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
+      mgr.getCurrentCheckName();
   // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete 
   // checker.
-  mgr.registerChecker<MallocChecker>()->Filter.CNewDeleteChecker = true;
+  if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) {
+    checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
+    checker->CheckNames[MallocChecker::CK_NewDeleteChecker] =
+        mgr.getCurrentCheckName();
+  }
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  registerCStringCheckerBasic(mgr); \
-  mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    registerCStringCheckerBasic(mgr);                                          \
+    MallocChecker *checker = mgr.registerChecker<MallocChecker>();             \
+    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
+    checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
+  }
 
 REGISTER_CHECKER(MallocPessimistic)
 REGISTER_CHECKER(MallocOptimistic)

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp Tue Feb 11 15:49:21 2014
@@ -213,11 +213,12 @@ void MallocOverflowSecurityChecker::Outp
        e = PossibleMallocOverflows.end();
        i != e;
        ++i) {
-    BR.EmitBasicReport(D, "malloc() size overflow", categories::UnixAPI,
-      "the computation of the size of the memory allocation may overflow",
-      PathDiagnosticLocation::createOperatorLoc(i->mulop,
-                                                BR.getSourceManager()),
-      i->mulop->getSourceRange());
+    BR.EmitBasicReport(
+        D, this, "malloc() size overflow", categories::UnixAPI,
+        "the computation of the size of the memory allocation may overflow",
+        PathDiagnosticLocation::createOperatorLoc(i->mulop,
+                                                  BR.getSourceManager()),
+        i->mulop->getSourceRange());
   }
 }
 
@@ -262,6 +263,7 @@ void MallocOverflowSecurityChecker::chec
   OutputPossibleOverflows(PossibleMallocOverflows, D, BR, mgr);
 }
 
-void ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
+void
+ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
   mgr.registerChecker<MallocOverflowSecurityChecker>();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp Tue Feb 11 15:49:21 2014
@@ -236,10 +236,8 @@ public:
             PathDiagnosticLocation::createBegin(i->AllocCall->getCallee(),
                 BR.getSourceManager(), ADC);
 
-        BR.EmitBasicReport(D, "Allocator sizeof operand mismatch",
-            categories::UnixAPI,
-            OS.str(),
-            L, Ranges);
+        BR.EmitBasicReport(D, this, "Allocator sizeof operand mismatch",
+                           categories::UnixAPI, OS.str(), L, Ranges);
       }
     }
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp Tue Feb 11 15:49:21 2014
@@ -59,7 +59,7 @@ void NSAutoreleasePoolChecker::checkPreO
     return;
 
   if (!BT)
-    BT.reset(new BugType("Use -drain instead of -release",
+    BT.reset(new BugType(this, "Use -drain instead of -release",
                          "API Upgrade (Apple)"));
 
   ExplodedNode *N = C.addTransition();

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp Tue Feb 11 15:49:21 2014
@@ -75,7 +75,7 @@ void NSErrorMethodChecker::checkASTDecl(
         "error occurred";
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(D, BR.getSourceManager());
-    BR.EmitBasicReport(D, "Bad return type when passing NSError**",
+    BR.EmitBasicReport(D, this, "Bad return type when passing NSError**",
                        "Coding conventions (Apple)", err, L);
   }
 }
@@ -123,7 +123,7 @@ void CFErrorFunctionChecker::checkASTDec
         "error occurred";
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(D, BR.getSourceManager());
-    BR.EmitBasicReport(D, "Bad return type when passing CFErrorRef*",
+    BR.EmitBasicReport(D, this, "Bad return type when passing CFErrorRef*",
                        "Coding conventions (Apple)", err, L);
   }
 }
@@ -136,14 +136,16 @@ namespace {
 
 class NSErrorDerefBug : public BugType {
 public:
-  NSErrorDerefBug() : BugType("NSError** null dereference",
-                              "Coding conventions (Apple)") {}
+  NSErrorDerefBug(const CheckerBase *Checker)
+      : BugType(Checker, "NSError** null dereference",
+                "Coding conventions (Apple)") {}
 };
 
 class CFErrorDerefBug : public BugType {
 public:
-  CFErrorDerefBug() : BugType("CFErrorRef* null dereference",
-                              "Coding conventions (Apple)") {}
+  CFErrorDerefBug(const CheckerBase *Checker)
+      : BugType(Checker, "CFErrorRef* null dereference",
+                "Coding conventions (Apple)") {}
 };
 
 }
@@ -264,11 +266,10 @@ void NSOrCFErrorDerefChecker::checkEvent
 
   BugType *bug = 0;
   if (isNSError)
-    bug = new NSErrorDerefBug();
+    bug = new NSErrorDerefBug(this);
   else
-    bug = new CFErrorDerefBug();
-  BugReport *report = new BugReport(*bug, os.str(),
-                                                    event.SinkNode);
+    bug = new CFErrorDerefBug(this);
+  BugReport *report = new BugReport(*bug, os.str(), event.SinkNode);
   BR.emitReport(report);
 }
 
@@ -305,14 +306,14 @@ static bool IsCFError(QualType T, Identi
 
 void ento::registerNSErrorChecker(CheckerManager &mgr) {
   mgr.registerChecker<NSErrorMethodChecker>();
-  NSOrCFErrorDerefChecker *
-    checker = mgr.registerChecker<NSOrCFErrorDerefChecker>();
+  NSOrCFErrorDerefChecker *checker =
+      mgr.registerChecker<NSOrCFErrorDerefChecker>();
   checker->ShouldCheckNSError = true;
 }
 
 void ento::registerCFErrorChecker(CheckerManager &mgr) {
   mgr.registerChecker<CFErrorFunctionChecker>();
-  NSOrCFErrorDerefChecker *
-    checker = mgr.registerChecker<NSOrCFErrorDerefChecker>();
+  NSOrCFErrorDerefChecker *checker =
+      mgr.registerChecker<NSOrCFErrorDerefChecker>();
   checker->ShouldCheckCFError = true;
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp Tue Feb 11 15:49:21 2014
@@ -150,7 +150,6 @@ void NoReturnFunctionChecker::checkPostO
   C.generateSink();
 }
 
-
 void ento::registerNoReturnFunctionChecker(CheckerManager &mgr) {
   mgr.registerChecker<NoReturnFunctionChecker>();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp Tue Feb 11 15:49:21 2014
@@ -162,8 +162,7 @@ BugReport *NonNullParamChecker::genRepor
   // the BugReport is passed to 'EmitWarning'.
   if (!BTAttrNonNull)
     BTAttrNonNull.reset(new BugType(
-                            "Argument with 'nonnull' attribute passed null",
-                            "API"));
+        this, "Argument with 'nonnull' attribute passed null", "API"));
 
   BugReport *R = new BugReport(*BTAttrNonNull,
                   "Null pointer passed as an argument to a 'nonnull' parameter",
@@ -177,7 +176,7 @@ BugReport *NonNullParamChecker::genRepor
 BugReport *NonNullParamChecker::genReportReferenceToNullPointer(
   const ExplodedNode *ErrorNode, const Expr *ArgE) const {
   if (!BTNullRefArg)
-    BTNullRefArg.reset(new BuiltinBug("Dereference of null pointer"));
+    BTNullRefArg.reset(new BuiltinBug(this, "Dereference of null pointer"));
 
   BugReport *R = new BugReport(*BTNullRefArg,
                                "Forming reference to null pointer",

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp Tue Feb 11 15:49:21 2014
@@ -45,8 +45,8 @@ void ObjCAtSyncChecker::checkPreStmt(con
   if (V.getAs<UndefinedVal>()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_undef)
-        BT_undef.reset(new BuiltinBug("Uninitialized value used as mutex "
-                                  "for @synchronized"));
+        BT_undef.reset(new BuiltinBug(this, "Uninitialized value used as mutex "
+                                            "for @synchronized"));
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
       bugreporter::trackNullOrUndefValue(N, Ex, *report);
@@ -68,8 +68,9 @@ void ObjCAtSyncChecker::checkPreStmt(con
       // a null mutex just means no synchronization occurs.
       if (ExplodedNode *N = C.addTransition(nullState)) {
         if (!BT_null)
-          BT_null.reset(new BuiltinBug("Nil value used as mutex for @synchronized() "
-                                   "(no synchronization will occur)"));
+          BT_null.reset(new BuiltinBug(
+              this, "Nil value used as mutex for @synchronized() "
+                    "(no synchronization will occur)"));
         BugReport *report =
           new BugReport(*BT_null, BT_null->getDescription(), N);
         bugreporter::trackNullOrUndefValue(N, Ex, *report);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp Tue Feb 11 15:49:21 2014
@@ -27,6 +27,7 @@ using namespace ento;
 namespace {
 class WalkAST : public StmtVisitor<WalkAST> {
   BugReporter &BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext* AC;
   ASTContext &ASTC;
   uint64_t PtrWidth;
@@ -71,9 +72,9 @@ class WalkAST : public StmtVisitor<WalkA
   }
 
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext* ac)
-  : BR(br), AC(ac), ASTC(AC->getASTContext()),
-    PtrWidth(ASTC.getTargetInfo().getPointerWidth(0)) {}
+  WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac)
+      : BR(br), Checker(checker), AC(ac), ASTC(AC->getASTContext()),
+        PtrWidth(ASTC.getTargetInfo().getPointerWidth(0)) {}
 
   // Statement visitor methods.
   void VisitChildren(Stmt *S);
@@ -142,9 +143,9 @@ void WalkAST::VisitCallExpr(CallExpr *CE
 
     PathDiagnosticLocation CELoc =
         PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-    BR.EmitBasicReport(AC->getDecl(),
-                       OsName.str(), categories::CoreFoundationObjectiveC,
-                       Os.str(), CELoc, Arg->getSourceRange());
+    BR.EmitBasicReport(AC->getDecl(), Checker, OsName.str(),
+                       categories::CoreFoundationObjectiveC, Os.str(), CELoc,
+                       Arg->getSourceRange());
   }
 
   // Recurse and check children.
@@ -163,7 +164,7 @@ public:
 
   void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
                         BugReporter &BR) const {
-    WalkAST walker(BR, Mgr.getAnalysisDeclContext(D));
+    WalkAST walker(BR, this, Mgr.getAnalysisDeclContext(D));
     walker.Visit(D->getBody());
   }
 };

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp Tue Feb 11 15:49:21 2014
@@ -33,7 +33,7 @@ class ObjCContainersChecker : public Che
   mutable OwningPtr<BugType> BT;
   inline void initBugType() const {
     if (!BT)
-      BT.reset(new BugType("CFArray API",
+      BT.reset(new BugType(this, "CFArray API",
                            categories::CoreFoundationObjectiveC));
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp Tue Feb 11 15:49:21 2014
@@ -212,7 +212,7 @@ void ObjCSuperCallChecker::checkASTDecl(
            << "' instance method in " << SuperclassName.str() << " subclass '"
            << *D << "' is missing a [super " << S.getAsString() << "] call";
 
-        BR.EmitBasicReport(MD, Name, categories::CoreFoundationObjectiveC,
+        BR.EmitBasicReport(MD, this, Name, categories::CoreFoundationObjectiveC,
                            os.str(), DLoc);
       }
     }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Tue Feb 11 15:49:21 2014
@@ -81,10 +81,10 @@ public:
 namespace {
 
 class InitSelfBug : public BugType {
-  const std::string desc;
 public:
-  InitSelfBug() : BugType("Missing \"self = [(super or self) init...]\"",
-                          categories::CoreFoundationObjectiveC) {}
+  InitSelfBug(const CheckerBase *Checker)
+      : BugType(Checker, "Missing \"self = [(super or self) init...]\"",
+                categories::CoreFoundationObjectiveC) {}
 };
 
 } // end anonymous namespace
@@ -147,7 +147,8 @@ static bool isInvalidSelf(const Expr *E,
 }
 
 static void checkForInvalidSelf(const Expr *E, CheckerContext &C,
-                                const char *errorStr) {
+                                const char *errorStr,
+                                const CheckerBase *Checker) {
   if (!E)
     return;
   
@@ -162,8 +163,7 @@ static void checkForInvalidSelf(const Ex
   if (!N)
     return;
 
-  BugReport *report =
-    new BugReport(*new InitSelfBug(), errorStr, N);
+  BugReport *report = new BugReport(*new InitSelfBug(Checker), errorStr, N);
   C.emitReport(report);
 }
 
@@ -205,9 +205,11 @@ void ObjCSelfInitChecker::checkPostStmt(
                                  C.getCurrentAnalysisDeclContext()->getDecl())))
     return;
 
-  checkForInvalidSelf(E->getBase(), C,
-    "Instance variable used while 'self' is not set to the result of "
-                                                 "'[(super or self) init...]'");
+  checkForInvalidSelf(
+      E->getBase(), C,
+      "Instance variable used while 'self' is not set to the result of "
+      "'[(super or self) init...]'",
+      this);
 }
 
 void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S,
@@ -218,8 +220,9 @@ void ObjCSelfInitChecker::checkPreStmt(c
     return;
 
   checkForInvalidSelf(S->getRetValue(), C,
-    "Returning 'self' while it is not set to the result of "
-                                                 "'[(super or self) init...]'");
+                      "Returning 'self' while it is not set to the result of "
+                      "'[(super or self) init...]'",
+                      this);
 }
 
 // When a call receives a reference to 'self', [Pre/Post]Call pass

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp Tue Feb 11 15:49:21 2014
@@ -111,7 +111,8 @@ static void Scan(IvarUsageMap &M, const
 }
 
 static void checkObjCUnusedIvar(const ObjCImplementationDecl *D,
-                                BugReporter &BR) {
+                                BugReporter &BR,
+                                const CheckerBase *Checker) {
 
   const ObjCInterfaceDecl *ID = D->getClassInterface();
   IvarUsageMap M;
@@ -172,7 +173,7 @@ static void checkObjCUnusedIvar(const Ob
 
       PathDiagnosticLocation L =
         PathDiagnosticLocation::create(I->first, BR.getSourceManager());
-      BR.EmitBasicReport(D, "Unused instance variable", "Optimization",
+      BR.EmitBasicReport(D, Checker, "Unused instance variable", "Optimization",
                          os.str(), L);
     }
 }
@@ -187,7 +188,7 @@ class ObjCUnusedIvarsChecker : public Ch
 public:
   void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    checkObjCUnusedIvar(D, BR);
+    checkObjCUnusedIvar(D, BR, this);
   }
 };
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp Tue Feb 11 15:49:21 2014
@@ -53,10 +53,11 @@ void PointerArithChecker::checkPreStmt(c
 
     if (ExplodedNode *N = C.addTransition()) {
       if (!BT)
-        BT.reset(new BuiltinBug("Dangerous pointer arithmetic",
-                            "Pointer arithmetic done on non-array variables "
-                            "means reliance on memory layout, which is "
-                            "dangerous."));
+        BT.reset(
+            new BuiltinBug(this, "Dangerous pointer arithmetic",
+                           "Pointer arithmetic done on non-array variables "
+                           "means reliance on memory layout, which is "
+                           "dangerous."));
       BugReport *R = new BugReport(*BT, BT->getDescription(), N);
       R->addRange(B->getSourceRange());
       C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp Tue Feb 11 15:49:21 2014
@@ -62,9 +62,10 @@ void PointerSubChecker::checkPreStmt(con
 
   if (ExplodedNode *N = C.addTransition()) {
     if (!BT)
-      BT.reset(new BuiltinBug("Pointer subtraction", 
-                          "Subtraction of two pointers that do not point to "
-                          "the same memory chunk may cause incorrect result."));
+      BT.reset(
+          new BuiltinBug(this, "Pointer subtraction",
+                         "Subtraction of two pointers that do not point to "
+                         "the same memory chunk may cause incorrect result."));
     BugReport *R = new BugReport(*BT, BT->getDescription(), N);
     R->addRange(B->getSourceRange());
     C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp Tue Feb 11 15:49:21 2014
@@ -102,7 +102,7 @@ void PthreadLockChecker::AcquireLock(Che
 
   if (state->contains<LockSet>(lockR)) {
     if (!BT_doublelock)
-      BT_doublelock.reset(new BugType("Double locking", "Lock checker"));
+      BT_doublelock.reset(new BugType(this, "Double locking", "Lock checker"));
     ExplodedNode *N = C.generateSink();
     if (!N)
       return;
@@ -165,7 +165,7 @@ void PthreadLockChecker::ReleaseLock(Che
   const MemRegion *firstLockR = LS.getHead();
   if (firstLockR != lockR) {
     if (!BT_lor)
-      BT_lor.reset(new BugType("Lock order reversal", "Lock checker"));
+      BT_lor.reset(new BugType(this, "Lock order reversal", "Lock checker"));
     ExplodedNode *N = C.generateSink();
     if (!N)
       return;
@@ -184,7 +184,6 @@ void PthreadLockChecker::ReleaseLock(Che
   C.addTransition(state);
 }
 
-
 void ento::registerPthreadLockChecker(CheckerManager &mgr) {
   mgr.registerChecker<PthreadLockChecker>();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Tue Feb 11 15:49:21 2014
@@ -1547,8 +1547,9 @@ namespace {
 
   class CFRefBug : public BugType {
   protected:
-    CFRefBug(StringRef name)
-    : BugType(name, categories::MemoryCoreFoundationObjectiveC) {}
+    CFRefBug(const CheckerBase *checker, StringRef name)
+        : BugType(checker, name, categories::MemoryCoreFoundationObjectiveC) {}
+
   public:
 
     // FIXME: Eventually remove.
@@ -1559,7 +1560,8 @@ namespace {
 
   class UseAfterRelease : public CFRefBug {
   public:
-    UseAfterRelease() : CFRefBug("Use-after-release") {}
+    UseAfterRelease(const CheckerBase *checker)
+        : CFRefBug(checker, "Use-after-release") {}
 
     const char *getDescription() const {
       return "Reference-counted object is used after it is released";
@@ -1568,7 +1570,7 @@ namespace {
 
   class BadRelease : public CFRefBug {
   public:
-    BadRelease() : CFRefBug("Bad release") {}
+    BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
 
     const char *getDescription() const {
       return "Incorrect decrement of the reference count of an object that is "
@@ -1578,8 +1580,8 @@ namespace {
 
   class DeallocGC : public CFRefBug {
   public:
-    DeallocGC()
-    : CFRefBug("-dealloc called while using garbage collection") {}
+    DeallocGC(const CheckerBase *checker)
+        : CFRefBug(checker, "-dealloc called while using garbage collection") {}
 
     const char *getDescription() const {
       return "-dealloc called while using garbage collection";
@@ -1588,8 +1590,8 @@ namespace {
 
   class DeallocNotOwned : public CFRefBug {
   public:
-    DeallocNotOwned()
-    : CFRefBug("-dealloc sent to non-exclusively owned object") {}
+    DeallocNotOwned(const CheckerBase *checker)
+        : CFRefBug(checker, "-dealloc sent to non-exclusively owned object") {}
 
     const char *getDescription() const {
       return "-dealloc sent to object that may be referenced elsewhere";
@@ -1598,8 +1600,8 @@ namespace {
 
   class OverAutorelease : public CFRefBug {
   public:
-    OverAutorelease()
-    : CFRefBug("Object autoreleased too many times") {}
+    OverAutorelease(const CheckerBase *checker)
+        : CFRefBug(checker, "Object autoreleased too many times") {}
 
     const char *getDescription() const {
       return "Object autoreleased too many times";
@@ -1608,8 +1610,8 @@ namespace {
 
   class ReturnedNotOwnedForOwned : public CFRefBug {
   public:
-    ReturnedNotOwnedForOwned()
-    : CFRefBug("Method should return an owned object") {}
+    ReturnedNotOwnedForOwned(const CheckerBase *checker)
+        : CFRefBug(checker, "Method should return an owned object") {}
 
     const char *getDescription() const {
       return "Object with a +0 retain count returned to caller where a +1 "
@@ -1619,8 +1621,7 @@ namespace {
 
   class Leak : public CFRefBug {
   public:
-    Leak(StringRef name)
-    : CFRefBug(name) {
+    Leak(const CheckerBase *checker, StringRef name) : CFRefBug(checker, name) {
       // Leaks should not be reported if they are post-dominated by a sink.
       setSuppressOnSink(true);
     }
@@ -2406,17 +2407,18 @@ public:
                                      bool GCEnabled) const {
     if (GCEnabled) {
       if (!leakWithinFunctionGC)
-        leakWithinFunctionGC.reset(new Leak("Leak of object when using "
-                                             "garbage collection"));
+        leakWithinFunctionGC.reset(new Leak(this, "Leak of object when using "
+                                                  "garbage collection"));
       return leakWithinFunctionGC.get();
     } else {
       if (!leakWithinFunction) {
         if (LOpts.getGC() == LangOptions::HybridGC) {
-          leakWithinFunction.reset(new Leak("Leak of object when not using "
+          leakWithinFunction.reset(new Leak(this,
+                                            "Leak of object when not using "
                                             "garbage collection (GC) in "
                                             "dual GC/non-GC code"));
         } else {
-          leakWithinFunction.reset(new Leak("Leak"));
+          leakWithinFunction.reset(new Leak(this, "Leak"));
         }
       }
       return leakWithinFunction.get();
@@ -2426,17 +2428,19 @@ public:
   CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts, bool GCEnabled) const {
     if (GCEnabled) {
       if (!leakAtReturnGC)
-        leakAtReturnGC.reset(new Leak("Leak of returned object when using "
+        leakAtReturnGC.reset(new Leak(this,
+                                      "Leak of returned object when using "
                                       "garbage collection"));
       return leakAtReturnGC.get();
     } else {
       if (!leakAtReturn) {
         if (LOpts.getGC() == LangOptions::HybridGC) {
-          leakAtReturn.reset(new Leak("Leak of returned object when not using "
+          leakAtReturn.reset(new Leak(this,
+                                      "Leak of returned object when not using "
                                       "garbage collection (GC) in dual "
                                       "GC/non-GC code"));
         } else {
-          leakAtReturn.reset(new Leak("Leak of returned object"));
+          leakAtReturn.reset(new Leak(this, "Leak of returned object"));
         }
       }
       return leakAtReturn.get();
@@ -3075,22 +3079,22 @@ void RetainCountChecker::processNonLeakE
       llvm_unreachable("Unhandled error.");
     case RefVal::ErrorUseAfterRelease:
       if (!useAfterRelease)
-        useAfterRelease.reset(new UseAfterRelease());
+        useAfterRelease.reset(new UseAfterRelease(this));
       BT = &*useAfterRelease;
       break;
     case RefVal::ErrorReleaseNotOwned:
       if (!releaseNotOwned)
-        releaseNotOwned.reset(new BadRelease());
+        releaseNotOwned.reset(new BadRelease(this));
       BT = &*releaseNotOwned;
       break;
     case RefVal::ErrorDeallocGC:
       if (!deallocGC)
-        deallocGC.reset(new DeallocGC());
+        deallocGC.reset(new DeallocGC(this));
       BT = &*deallocGC;
       break;
     case RefVal::ErrorDeallocNotOwned:
       if (!deallocNotOwned)
-        deallocNotOwned.reset(new DeallocNotOwned());
+        deallocNotOwned.reset(new DeallocNotOwned(this));
       BT = &*deallocNotOwned;
       break;
   }
@@ -3342,7 +3346,7 @@ void RetainCountChecker::checkReturnWith
       ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
       if (N) {
         if (!returnNotOwnedForOwned)
-          returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned());
+          returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
 
         CFRefReport *report =
             new CFRefReport(*returnNotOwnedForOwned,
@@ -3530,7 +3534,7 @@ RetainCountChecker::handleAutoreleaseCou
     os << "has a +" << V.getCount() << " retain count";
 
     if (!overAutorelease)
-      overAutorelease.reset(new OverAutorelease());
+      overAutorelease.reset(new OverAutorelease(this));
 
     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
     CFRefReport *report =

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp Tue Feb 11 15:49:21 2014
@@ -69,9 +69,10 @@ void ReturnPointerRangeChecker::checkPre
     // FIXME: This bug correspond to CWE-466.  Eventually we should have bug
     // types explicitly reference such exploit categories (when applicable).
     if (!BT)
-      BT.reset(new BuiltinBug("Return of pointer value outside of expected range",
-           "Returned pointer value points outside the original object "
-           "(potential buffer overflow)"));
+      BT.reset(new BuiltinBug(
+          this, "Return of pointer value outside of expected range",
+          "Returned pointer value points outside the original object "
+          "(potential buffer overflow)"));
 
     // FIXME: It would be nice to eventually make this diagnostic more clear,
     // e.g., by referencing the original declaration or by saying *why* this

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp Tue Feb 11 15:49:21 2014
@@ -94,9 +94,9 @@ static void emitBug(CheckerContext &C, B
 
 void ReturnUndefChecker::emitUndef(CheckerContext &C, const Expr *RetE) const {
   if (!BT_Undef)
-    BT_Undef.reset(new BuiltinBug("Garbage return value",
-                                  "Undefined or garbage value "
-                                    "returned to caller"));
+    BT_Undef.reset(
+        new BuiltinBug(this, "Garbage return value",
+                       "Undefined or garbage value returned to caller"));
   emitBug(C, *BT_Undef, RetE);
 }
 
@@ -113,7 +113,7 @@ void ReturnUndefChecker::checkReference(
 
   // The return value is known to be null. Emit a bug report.
   if (!BT_NullReference)
-    BT_NullReference.reset(new BuiltinBug("Returning null reference"));
+    BT_NullReference.reset(new BuiltinBug(this, "Returning null reference"));
 
   emitBug(C, *BT_NullReference, RetE, bugreporter::getDerefExpr(RetE));
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp Tue Feb 11 15:49:21 2014
@@ -109,11 +109,11 @@ public:
 
 SimpleStreamChecker::SimpleStreamChecker() : IIfopen(0), IIfclose(0) {
   // Initialize the bug types.
-  DoubleCloseBugType.reset(new BugType("Double fclose",
-                                       "Unix Stream API Error"));
+  DoubleCloseBugType.reset(
+      new BugType(this, "Double fclose", "Unix Stream API Error"));
 
-  LeakBugType.reset(new BugType("Resource Leak",
-                                "Unix Stream API Error"));
+  LeakBugType.reset(
+      new BugType(this, "Resource Leak", "Unix Stream API Error"));
   // Sinks are higher importance bugs as well as calls to assert() or exit(0).
   LeakBugType->setSuppressOnSink(true);
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp Tue Feb 11 15:49:21 2014
@@ -100,8 +100,8 @@ void StackAddrEscapeChecker::EmitStackEr
     return;
 
   if (!BT_returnstack)
-   BT_returnstack.reset(
-                 new BuiltinBug("Return of address to stack-allocated memory"));
+    BT_returnstack.reset(
+        new BuiltinBug(this, "Return of address to stack-allocated memory"));
 
   // Generate a report for this bug.
   SmallString<512> buf;
@@ -217,11 +217,11 @@ void StackAddrEscapeChecker::checkEndFun
 
   if (!BT_stackleak)
     BT_stackleak.reset(
-      new BuiltinBug("Stack address stored into global variable",
-                     "Stack address was saved into a global variable. "
-                     "This is dangerous because the address will become "
-                     "invalid after returning from the function"));
-  
+        new BuiltinBug(this, "Stack address stored into global variable",
+                       "Stack address was saved into a global variable. "
+                       "This is dangerous because the address will become "
+                       "invalid after returning from the function"));
+
   for (unsigned i = 0, e = cb.V.size(); i != e; ++i) {
     // Generate a report for this bug.
     SmallString<512> buf;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp Tue Feb 11 15:49:21 2014
@@ -270,9 +270,10 @@ void StreamChecker::Fseek(CheckerContext
 
   if (ExplodedNode *N = C.addTransition(state)) {
     if (!BT_illegalwhence)
-      BT_illegalwhence.reset(new BuiltinBug("Illegal whence argument",
-					"The whence argument to fseek() should be "
-					"SEEK_SET, SEEK_END, or SEEK_CUR."));
+      BT_illegalwhence.reset(
+          new BuiltinBug(this, "Illegal whence argument",
+                         "The whence argument to fseek() should be "
+                         "SEEK_SET, SEEK_END, or SEEK_CUR."));
     BugReport *R = new BugReport(*BT_illegalwhence, 
 				 BT_illegalwhence->getDescription(), N);
     C.emitReport(R);
@@ -348,8 +349,8 @@ ProgramStateRef StreamChecker::CheckNull
   if (!stateNotNull && stateNull) {
     if (ExplodedNode *N = C.generateSink(stateNull)) {
       if (!BT_nullfp)
-        BT_nullfp.reset(new BuiltinBug("NULL stream pointer",
-                                     "Stream pointer might be NULL."));
+        BT_nullfp.reset(new BuiltinBug(this, "NULL stream pointer",
+                                       "Stream pointer might be NULL."));
       BugReport *R =new BugReport(*BT_nullfp, BT_nullfp->getDescription(), N);
       C.emitReport(R);
     }
@@ -378,9 +379,9 @@ ProgramStateRef StreamChecker::CheckDoub
     ExplodedNode *N = C.generateSink();
     if (N) {
       if (!BT_doubleclose)
-        BT_doubleclose.reset(new BuiltinBug("Double fclose",
-                                        "Try to close a file Descriptor already"
-                                        " closed. Cause undefined behaviour."));
+        BT_doubleclose.reset(new BuiltinBug(
+            this, "Double fclose", "Try to close a file Descriptor already"
+                                   " closed. Cause undefined behaviour."));
       BugReport *R = new BugReport(*BT_doubleclose,
                                    BT_doubleclose->getDescription(), N);
       C.emitReport(R);
@@ -407,8 +408,9 @@ void StreamChecker::checkDeadSymbols(Sym
       ExplodedNode *N = C.generateSink();
       if (N) {
         if (!BT_ResourceLeak)
-          BT_ResourceLeak.reset(new BuiltinBug("Resource Leak", 
-                         "Opened File never closed. Potential Resource leak."));
+          BT_ResourceLeak.reset(new BuiltinBug(
+              this, "Resource Leak",
+              "Opened File never closed. Potential Resource leak."));
         BugReport *R = new BugReport(*BT_ResourceLeak, 
                                      BT_ResourceLeak->getDescription(), N);
         C.emitReport(R);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp Tue Feb 11 15:49:21 2014
@@ -38,7 +38,7 @@ public:
 
 inline void TaintTesterChecker::initBugType() const {
   if (!BT)
-    BT.reset(new BugType("Tainted data", "General"));
+    BT.reset(new BugType(this, "Tainted data", "General"));
 }
 
 void TaintTesterChecker::checkPostStmt(const Expr *E,

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp Tue Feb 11 15:49:21 2014
@@ -67,8 +67,8 @@ void UndefBranchChecker::checkBranchCond
     ExplodedNode *N = Ctx.generateSink();
     if (N) {
       if (!BT)
-        BT.reset(
-               new BuiltinBug("Branch condition evaluates to a garbage value"));
+        BT.reset(new BuiltinBug(
+            this, "Branch condition evaluates to a garbage value"));
 
       // What's going on here: we want to highlight the subexpression of the
       // condition that is the most likely source of the "uninitialized

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp Tue Feb 11 15:49:21 2014
@@ -79,7 +79,8 @@ UndefCapturedBlockVarChecker::checkPostS
           state->getSVal(I.getOriginalRegion()).getAs<UndefinedVal>()) {
       if (ExplodedNode *N = C.generateSink()) {
         if (!BT)
-          BT.reset(new BuiltinBug("uninitialized variable captured by block"));
+          BT.reset(
+              new BuiltinBug(this, "uninitialized variable captured by block"));
 
         // Generate a bug report.
         SmallString<128> buf;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp Tue Feb 11 15:49:21 2014
@@ -55,7 +55,8 @@ void UndefResultChecker::checkPostStmt(c
       return;
     
     if (!BT)
-      BT.reset(new BuiltinBug("Result of operation is garbage or undefined"));
+      BT.reset(
+          new BuiltinBug(this, "Result of operation is garbage or undefined"));
 
     SmallString<256> sbuf;
     llvm::raw_svector_ostream OS(sbuf);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp Tue Feb 11 15:49:21 2014
@@ -50,7 +50,7 @@ UndefinedArraySubscriptChecker::checkPre
   if (!N)
     return;
   if (!BT)
-    BT.reset(new BuiltinBug("Array subscript is undefined"));
+    BT.reset(new BuiltinBug(this, "Array subscript is undefined"));
 
   // Generate a report for this bug.
   BugReport *R = new BugReport(*BT, BT->getName(), N);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp Tue Feb 11 15:49:21 2014
@@ -54,7 +54,7 @@ void UndefinedAssignmentChecker::checkBi
   const char *str = "Assigned value is garbage or undefined";
 
   if (!BT)
-    BT.reset(new BuiltinBug(str));
+    BT.reset(new BuiltinBug(this, str));
 
   // Generate a report for this bug.
   const Expr *ex = 0;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp Tue Feb 11 15:49:21 2014
@@ -57,21 +57,15 @@ private:
                             const unsigned numArgs,
                             const unsigned sizeArg,
                             const char *fn) const;
+  void LazyInitialize(OwningPtr<BugType> &BT, const char *name) const {
+    if (BT)
+      return;
+    BT.reset(new BugType(this, name, categories::UnixAPI));
+  }
 };
 } //end anonymous namespace
 
 //===----------------------------------------------------------------------===//
-// Utility functions.
-//===----------------------------------------------------------------------===//
-
-static inline void LazyInitialize(OwningPtr<BugType> &BT,
-                                  const char *name) {
-  if (BT)
-    return;
-  BT.reset(new BugType(name, categories::UnixAPI));
-}
-
-//===----------------------------------------------------------------------===//
 // "open" (man 2 open)
 //===----------------------------------------------------------------------===//
 
@@ -217,7 +211,7 @@ bool UnixAPIChecker::ReportZeroByteAlloc
     return false;
 
   LazyInitialize(BT_mallocZero,
-    "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)");
+                 "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)");
 
   SmallString<256> S;
   llvm::raw_svector_ostream os(S);    

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp Tue Feb 11 15:49:21 2014
@@ -165,7 +165,7 @@ void UnreachableCodeChecker::checkEndAna
     if (SM.isInSystemHeader(SL) || SM.isInExternCSystemHeader(SL))
       continue;
 
-    B.EmitBasicReport(D, "Unreachable code", "Dead code",
+    B.EmitBasicReport(D, this, "Unreachable code", "Dead code",
                       "This statement is never executed", DL, SR);
   }
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp Tue Feb 11 15:49:21 2014
@@ -51,7 +51,8 @@ void VLASizeChecker::reportBug(VLASize_K
     return;
 
   if (!BT)
-    BT.reset(new BuiltinBug("Dangerous variable-length array (VLA) declaration"));
+    BT.reset(new BuiltinBug(
+        this, "Dangerous variable-length array (VLA) declaration"));
 
   SmallString<256> buf;
   llvm::raw_svector_ostream os(buf);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp Tue Feb 11 15:49:21 2014
@@ -28,6 +28,7 @@ using namespace ento;
 namespace {
 
 class WalkAST : public StmtVisitor<WalkAST> {
+  const CheckerBase *Checker;
   BugReporter &BR;
   AnalysisDeclContext *AC;
 
@@ -58,11 +59,10 @@ class WalkAST : public StmtVisitor<WalkA
   const CallExpr *visitingCallExpr;
   
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext *ac)
-    : BR(br),
-      AC(ac),
-      visitingCallExpr(0) {}
-  
+  WalkAST(const CheckerBase *checker, BugReporter &br,
+          AnalysisDeclContext *ac)
+      : Checker(checker), BR(br), AC(ac), visitingCallExpr(0) {}
+
   bool hasWork() const { return !WList.empty(); }
 
   /// This method adds a CallExpr to the worklist and marks the callee as
@@ -187,21 +187,19 @@ void WalkAST::ReportVirtualCall(const Ca
   if (isPure) {
     os << "\n" <<  "Call pure virtual functions during construction or "
        << "destruction may leads undefined behaviour";
-    BR.EmitBasicReport(AC->getDecl(),
+    BR.EmitBasicReport(AC->getDecl(), Checker,
                        "Call pure virtual function during construction or "
                        "Destruction",
-                       "Cplusplus",
-                       os.str(), CELoc, R);
+                       "Cplusplus", os.str(), CELoc, R);
     return;
   }
   else {
     os << "\n" << "Call virtual functions during construction or "
        << "destruction will never go to a more derived class";
-    BR.EmitBasicReport(AC->getDecl(),
+    BR.EmitBasicReport(AC->getDecl(), Checker,
                        "Call virtual function during construction or "
                        "Destruction",
-                       "Cplusplus",
-                       os.str(), CELoc, R);
+                       "Cplusplus", os.str(), CELoc, R);
     return;
   }
 }
@@ -215,7 +213,7 @@ class VirtualCallChecker : public Checke
 public:
   void checkASTDecl(const CXXRecordDecl *RD, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    WalkAST walker(BR, mgr.getAnalysisDeclContext(RD));
+    WalkAST walker(this, BR, mgr.getAnalysisDeclContext(RD));
 
     // Check the constructors.
     for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(), E = RD->ctor_end();

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Tue Feb 11 15:49:21 2014
@@ -3420,7 +3420,8 @@ void BugReporter::FlushReport(BugReport
   BugType& BT = exampleReport->getBugType();
 
   OwningPtr<PathDiagnostic>
-    D(new PathDiagnostic(exampleReport->getDeclWithIssue(),
+    D(new PathDiagnostic(exampleReport->getBugType().getCheckName(),
+                         exampleReport->getDeclWithIssue(),
                          exampleReport->getBugType().getName(),
                          exampleReport->getDescription(),
                          exampleReport->getShortDescription(/*Fallback=*/false),
@@ -3472,13 +3473,21 @@ void BugReporter::FlushReport(BugReport
 }
 
 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
-                                  StringRef name,
-                                  StringRef category,
+                                  const CheckerBase *Checker,
+                                  StringRef Name, StringRef Category,
+                                  StringRef Str, PathDiagnosticLocation Loc,
+                                  ArrayRef<SourceRange> Ranges) {
+  EmitBasicReport(DeclWithIssue, Checker->getCheckName(), Name, Category, Str,
+                  Loc, Ranges);
+}
+void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
+                                  CheckName CheckName,
+                                  StringRef name, StringRef category,
                                   StringRef str, PathDiagnosticLocation Loc,
                                   ArrayRef<SourceRange> Ranges) {
 
   // 'BT' is owned by BugReporter.
-  BugType *BT = getBugTypeForName(name, category);
+  BugType *BT = getBugTypeForName(CheckName, name, category);
   BugReport *R = new BugReport(*BT, str, Loc);
   R->setDeclWithIssue(DeclWithIssue);
   for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
@@ -3487,15 +3496,16 @@ void BugReporter::EmitBasicReport(const
   emitReport(R);
 }
 
-BugType *BugReporter::getBugTypeForName(StringRef name,
+BugType *BugReporter::getBugTypeForName(CheckName CheckName, StringRef name,
                                         StringRef category) {
   SmallString<136> fullDesc;
-  llvm::raw_svector_ostream(fullDesc) << name << ":" << category;
+  llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name
+                                      << ":" << category;
   llvm::StringMapEntry<BugType *> &
       entry = StrBugTypes.GetOrCreateValue(fullDesc);
   BugType *BT = entry.getValue();
   if (!BT) {
-    BT = new BugType(name, category);
+    BT = new BugType(CheckName, name, category);
     entry.setValue(BT);
   }
   return BT;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp Tue Feb 11 15:49:21 2014
@@ -22,6 +22,8 @@ StringRef CheckerBase::getTagDescription
   return "A Checker";  
 }
 
+CheckName CheckerBase::getCheckName() const { return Name; }
+
 void Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
              check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
              check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp Tue Feb 11 15:49:21 2014
@@ -106,6 +106,7 @@ void CheckerRegistry::initializeManager(
   // Initialize the CheckerManager with all enabled checkers.
   for (CheckerInfoSet::iterator
          i = enabledCheckers.begin(), e = enabledCheckers.end(); i != e; ++i) {
+    checkerMgr.setCurrentCheckName(CheckName((*i)->FullName));
     (*i)->Initialize(checkerMgr);
   }
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=201186&r1=201185&r2=201186&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Tue Feb 11 15:49:21 2014
@@ -106,12 +106,13 @@ void PathPieces::flattenTo(PathPieces &P
 
 PathDiagnostic::~PathDiagnostic() {}
 
-PathDiagnostic::PathDiagnostic(const Decl *declWithIssue,
+PathDiagnostic::PathDiagnostic(StringRef CheckName, const Decl *declWithIssue,
                                StringRef bugtype, StringRef verboseDesc,
                                StringRef shortDesc, StringRef category,
                                PathDiagnosticLocation LocationToUnique,
                                const Decl *DeclToUnique)
-  : DeclWithIssue(declWithIssue),
+  : CheckName(CheckName),
+    DeclWithIssue(declWithIssue),
     BugType(StripTrailingDots(bugtype)),
     VerboseDesc(StripTrailingDots(verboseDesc)),
     ShortDesc(StripTrailingDots(shortDesc)),





More information about the cfe-commits mailing list