]> granicus.if.org Git - clang/commitdiff
Static Analyzer Diagnostics: Kill the addVisitorCreator(callbackTy, void*) API in...
authorAnna Zaks <ganna@apple.com>
Fri, 19 Aug 2011 22:33:38 +0000 (22:33 +0000)
committerAnna Zaks <ganna@apple.com>
Fri, 19 Aug 2011 22:33:38 +0000 (22:33 +0000)
1) Create a header file to expose the predefined visitors. And move the parent(BugReporterVisitor) there as well.

2) Remove the registerXXXVisitor functions - the Visitor constructors/getters can be used now to create the object. One exception is registerVarDeclsLastStore(), which registers more then one visitor, so make it static member of FindLastStoreBRVisitor.

3) Modify all the checkers to use the new API.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138126 91177308-0d34-0410-b5e6-96231b3b80d8

20 files changed:
include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h [new file with mode: 0644]
lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
lib/StaticAnalyzer/Checkers/CStringChecker.cpp
lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
lib/StaticAnalyzer/Core/BugReporter.cpp
lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

index 421e305508a7afb9efaa9001fa07137fa55d9ae5..a8923be63f650dff20118a3bd22649c6747e02d2 100644 (file)
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_GR_BUGREPORTER
 
 #include "clang/Basic/SourceLocation.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableList.h"
@@ -48,24 +49,6 @@ class BugType;
 // Interface for individual bug reports.
 //===----------------------------------------------------------------------===//
 
-class BugReporterVisitor : public llvm::FoldingSetNode {
-public:
-  virtual ~BugReporterVisitor();
-
-  /// \brief Return a diagnostic piece which should be associated with the
-  /// given node.
-  ///
-  /// The last parameter can be used to register a new visitor with the given
-  /// BugReport while processing a node.
-  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                         const ExplodedNode *PrevN,
-                                         BugReporterContext &BRC,
-                                         BugReport &BR) = 0;
-
-  virtual bool isOwnedByReporterContext() { return true; }
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
-};
-
 /// This class provides an interface through which checkers can create
 /// individual bug reports.
 class BugReport : public BugReporterVisitor {
@@ -77,14 +60,12 @@ public:
             getOriginalNode(const ExplodedNode *N) = 0;
   };
 
-  typedef void (*VisitorCreator)(BugReport &BR, const void *data);
   typedef const SourceRange *ranges_iterator;
   typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator;
 
 protected:
   friend class BugReporter;
   friend class BugReportEquivClass;
-  typedef SmallVector<std::pair<VisitorCreator, const void*>, 2> Creators;
 
   BugType& BT;
   std::string ShortDescription;
@@ -178,11 +159,7 @@ public:
   /// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
   /// registerFindLastStore(), registerNilReceiverVisitor(), and
   /// registerVarDeclsLastStore().
-  void addVisitorCreator(VisitorCreator creator, const void *data) {
-    creator(*this, data);
-  }
-
-  void addVisitor(BugReporterVisitor* visitor);
+  void addVisitor(BugReporterVisitor *visitor);
 
        /// Iterators through the custom diagnostic visitors.
   visitor_iterator visitor_begin() { return Callbacks.begin(); }
@@ -445,30 +422,6 @@ public:
   virtual BugReport::NodeResolver& getNodeResolver() = 0;
 };
 
-//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-
-namespace bugreporter {
-
-const Stmt *GetDerefExpr(const ExplodedNode *N);
-const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetCalleeExpr(const ExplodedNode *N);
-const Stmt *GetRetValExpr(const ExplodedNode *N);
-
-void registerConditionVisitor(BugReport &BR);
-
-void registerTrackNullOrUndefValue(BugReport &BR, const void *stmt);
-
-void registerFindLastStore(BugReport &BR, const void *memregion);
-
-void registerNilReceiverVisitor(BugReport &BR);
-
-void registerVarDeclsLastStore(BugReport &BR, const void *stmt);
-
-} // end namespace clang::bugreporter
-
-//===----------------------------------------------------------------------===//
-
 } // end GR namespace
 
 } // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
new file mode 100644 (file)
index 0000000..4533616
--- /dev/null
@@ -0,0 +1,166 @@
+//===---  BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file declares BugReporterVisitors, which are used to generate enhanced
+//  diagnostic traces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR
+#define LLVM_CLANG_GR_BUGREPORTERVISITOR
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/FoldingSet.h"
+
+namespace clang {
+
+namespace ento {
+
+class BugReport;
+class BugReporterContext;
+class ExplodedNode;
+class MemRegion;
+class PathDiagnosticPiece;
+
+class BugReporterVisitor : public llvm::FoldingSetNode {
+public:
+  virtual ~BugReporterVisitor();
+
+  /// \brief Return a diagnostic piece which should be associated with the
+  /// given node.
+  ///
+  /// The last parameter can be used to register a new visitor with the given
+  /// BugReport while processing a node.
+  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                         const ExplodedNode *PrevN,
+                                         BugReporterContext &BRC,
+                                         BugReport &BR) = 0;
+
+  virtual bool isOwnedByReporterContext() { return true; }
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
+};
+
+class FindLastStoreBRVisitor : public BugReporterVisitor {
+  const MemRegion *R;
+  SVal V;
+  bool satisfied;
+  const ExplodedNode *StoreSite;
+
+public:
+  /// \brief Convenience method to create a visitor given only the MemRegion.
+  /// Returns NULL if the visitor cannot be created. For example, when the
+  /// corresponding value is unknown.
+  static BugReporterVisitor *createVisitorObject(const ExplodedNode *N,
+                                                 const MemRegion *R);
+
+  /// Creates a visitor for every VarDecl inside a Stmt and registers it with
+  /// the BugReport.
+  static void registerStatementVarDecls(BugReport &BR, const Stmt *S);
+
+  FindLastStoreBRVisitor(SVal v, const MemRegion *r)
+  : R(r), V(v), satisfied(false), StoreSite(0) {
+    assert (!V.isUnknown() && "Cannot track unknown value.");
+
+    // TODO: Does it make sense to allow undef values here?
+    // (If not, also see UndefCapturedBlockVarChecker)?
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR);
+};
+
+class TrackConstraintBRVisitor : public BugReporterVisitor {
+  DefinedSVal Constraint;
+  const bool Assumption;
+  bool isSatisfied;
+
+public:
+  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
+  : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR);
+};
+
+class NilReceiverBRVisitor : public BugReporterVisitor {
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR);
+};
+
+/// Visitor that tries to report interesting diagnostics from conditions.
+class ConditionBRVisitor : public BugReporterVisitor {
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                         const ExplodedNode *Prev,
+                                         BugReporterContext &BRC,
+                                         BugReport &BR);
+
+  PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
+                                       const ProgramState *CurrentState,
+                                       const ProgramState *PrevState,
+                                       const CFGBlock *srcBlk,
+                                       const CFGBlock *dstBlk,
+                                       BugReporterContext &BRC);
+
+  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
+                                     bool tookTrue,
+                                     BugReporterContext &BRC);
+
+  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
+                                     const DeclRefExpr *DR,
+                                     const bool tookTrue,
+                                     BugReporterContext &BRC);
+
+  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
+                                     const BinaryOperator *BExpr,
+                                     const bool tookTrue,
+                                     BugReporterContext &BRC);
+
+  bool patternMatch(const Expr *Ex,
+                    llvm::raw_ostream &Out,
+                    BugReporterContext &BRC);
+};
+
+namespace bugreporter {
+
+BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
+                                                    const Stmt *S);
+
+const Stmt *GetDerefExpr(const ExplodedNode *N);
+const Stmt *GetDenomExpr(const ExplodedNode *N);
+const Stmt *GetCalleeExpr(const ExplodedNode *N);
+const Stmt *GetRetValExpr(const ExplodedNode *N);
+
+} // end namespace clang
+} // end namespace ento
+} // end namespace bugreporter
+
+
+#endif //LLVM_CLANG_GR__BUGREPORTERVISITOR
index 285b3920fa40006560b62ca93df85bf57ecccdcf..8296eb93c5aed18837389eff3475c8e4b1c0e447 100644 (file)
@@ -101,15 +101,14 @@ void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
                                "API"));
 
         BugReport *R =
-          new BugReport(*BT,
-                                "Null pointer passed as an argument to a "
-                                "'nonnull' parameter", errorNode);
+          new BugReport(*BT, "Null pointer passed as an argument to a "
+                             "'nonnull' parameter", errorNode);
 
         // Highlight the range of the argument that was null.
         const Expr *arg = *I;
         R->addRange(arg->getSourceRange());
-        R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, arg);
-
+        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
+                                                                   arg));
         // Emit the bug report.
         C.EmitReport(R);
       }
index da592050ebc7e3d3051c947121489617919b8bae..1631df8af9883d74d4b68d1c201305fd62250d27 100644 (file)
@@ -414,7 +414,7 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
 
     BugReport *report = new BugReport(*BT, description, N);
     report->addRange(Arg->getSourceRange());
-    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Arg);
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Arg));
     C.EmitReport(report);
     return;
   }
index c5d4379fcbb949e9b903c5b125c8d5c537bc622d..d043e2d8aef3d26320df69b5edfa6c424b24c4fe 100644 (file)
@@ -231,7 +231,7 @@ const ProgramState *CStringChecker::checkNonNull(CheckerContext &C,
     BugReport *report = new BugReport(*BT, os.str(), N);
 
     report->addRange(S->getSourceRange());
-    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S));
     C.EmitReport(report);
     return NULL;
   }
index 191d4bba02a36e92f137e1a9feca1ab7def53142..ba1dae873877dbbd995403c853a7400c1879b42c 100644 (file)
@@ -65,8 +65,8 @@ void CallAndMessageChecker::EmitBadCall(BugType *BT, CheckerContext &C,
     return;
 
   BugReport *R = new BugReport(*BT, BT->getName(), N);
-  R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                       bugreporter::GetCalleeExpr(N));
+  R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                               bugreporter::GetCalleeExpr(N)));
   C.EmitReport(R);
 }
 
@@ -95,7 +95,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
       BugReport *R = new BugReport(*BT, BT->getName(), N);
       R->addRange(argRange);
       if (argEx)
-        R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, argEx);
+        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx));
       C.EmitReport(R);
     }
     return true;
@@ -230,8 +230,8 @@ void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
         BugReport *R =
           new BugReport(*BT_msg_undef, BT_msg_undef->getName(), N);
         R->addRange(receiver->getSourceRange());
-        R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                             receiver);
+        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                                                   receiver));
         C.EmitReport(R);
       }
       return;
@@ -275,8 +275,8 @@ void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
   BugReport *report = new BugReport(*BT_msg_ret, os.str(), N);
   if (const Expr *receiver = msg.getInstanceReceiver()) {
     report->addRange(receiver->getSourceRange());
-    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                              receiver);
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                                                    receiver));
   }
   C.EmitReport(report);
 }
index 22af688547c69ff7d743c407ae68944b2793d92e..c416dd8e8edf8bded12fff609246a31ecea98c21 100644 (file)
@@ -75,8 +75,8 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad,
 
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
-      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                                bugreporter::GetDerefExpr(N));
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                        bugreporter::GetDerefExpr(N)));
       C.EmitReport(report);
     }
     return;
@@ -162,8 +162,8 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad,
                               buf.empty() ? BT_null->getDescription():buf.str(),
                               N);
 
-      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                                bugreporter::GetDerefExpr(N));
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                        bugreporter::GetDerefExpr(N)));
 
       for (SmallVectorImpl<SourceRange>::iterator
             I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
index d87c773d6e70368cc0f3501ecd8199d44d639d52..75b7cc47aa79104b1a49d43054e2d1608e1e448e 100644 (file)
@@ -63,8 +63,8 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
       BugReport *R = 
         new BugReport(*BT, BT->getDescription(), N);
 
-      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                           bugreporter::GetDenomExpr(N));
+      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                   bugreporter::GetDenomExpr(N)));
 
       C.EmitReport(R);
     }
index af819ecf30e7b6f4a79d5ff549d6a0be37a6f60e..46f06a0a848088b15f12d2e5868580feec205103 100644 (file)
@@ -413,12 +413,12 @@ void IdempotentOperationChecker::checkEndAnalysis(ExplodedGraph &G,
       if (LHSRelevant) {
         const Expr *LHS = i->first->getLHS();
         report->addRange(LHS->getSourceRange());
-        report->addVisitorCreator(bugreporter::registerVarDeclsLastStore, LHS);
+        FindLastStoreBRVisitor::registerStatementVarDecls(*report, LHS);
       }
       if (RHSRelevant) {
         const Expr *RHS = i->first->getRHS();
         report->addRange(i->first->getRHS()->getSourceRange());
-        report->addVisitorCreator(bugreporter::registerVarDeclsLastStore, RHS);
+        FindLastStoreBRVisitor::registerStatementVarDecls(*report, RHS);
       }
 
       BR.EmitReport(report);
index 7b964a44ba8151fce60cb352700bee4d3a152c77..3e4e07b65057b306b2f9d693f45f94c84aa2edaa 100644 (file)
@@ -49,7 +49,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
                                   "for @synchronized"));
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
-      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
       C.EmitReport(report);
     }
     return;
@@ -72,8 +72,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
                                    "(no synchronization will occur)"));
         BugReport *report =
           new BugReport(*BT_null, BT_null->getDescription(), N);
-        report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                                  Ex);
+        report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
 
         C.EmitReport(report);
         return;
index 979c107792554730bb487fd3d9a613a68971ba29..e8c8d902a5e56cc5cc8785095d27a238a33a3aec 100644 (file)
@@ -54,7 +54,7 @@ void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS,
     new BugReport(*BT, BT->getDescription(), N);
 
   report->addRange(RetE->getSourceRange());
-  report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, RetE);
+  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE));
 
   C.EmitReport(report);
 }
index f29cac60282db257806580b876532cc1e572f745..de20e89dff70bcad1f86a6e69cc936c28b398966 100644 (file)
@@ -99,8 +99,8 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
       Ex = FindIt.FindExpr(Ex);
 
       // Emit the bug report.
-      BugReport *R = new BugReport(*BT, BT->getDescription(),N);
-      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
+      BugReport *R = new BugReport(*BT, BT->getDescription(), N);
+      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
       R->addRange(Ex->getSourceRange());
 
       Eng.getBugReporter().EmitReport(R);
index 486ddbb1355c66a738a2664f220ba24a1eb78b9d..2aebed9346d6672a00626ad25fbf4f13b781a9f1 100644 (file)
@@ -74,8 +74,9 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
     // Get the VarRegion associated with VD in the local stack frame.
     const LocationContext *LC = C.getPredecessor()->getLocationContext();
     VR = C.getSValBuilder().getRegionManager().getVarRegion(VD, LC);
+    SVal VRVal = state->getSVal(VR);
 
-    if (state->getSVal(VR).isUndef())
+    if (VRVal.isUndef())
       if (ExplodedNode *N = C.generateSink()) {
         if (!BT)
           BT.reset(new BuiltinBug("uninitialized variable captured by block"));
@@ -90,7 +91,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
         BugReport *R = new BugReport(*BT, os.str(), N);
         if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD))
           R->addRange(Ex->getSourceRange());
-        R->addVisitorCreator(bugreporter::registerFindLastStore, VR);
+        R->addVisitor(new FindLastStoreBRVisitor(VRVal, VR));
         // need location of block
         C.EmitReport(R);
       }
index 1074688562d7cc5aa83c3afa5c05e7fb65325ba1..7ae966865c864237c2065b7417621a89522d2f03 100644 (file)
@@ -74,10 +74,10 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
     BugReport *report = new BugReport(*BT, OS.str(), N);
     if (Ex) {
       report->addRange(Ex->getSourceRange());
-      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
     }
     else
-      report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, B);
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, B));
     C.EmitReport(report);
   }
 }
index 92e656109fff3de31dbaf4878f8cc13da3ab4016..bb6831b783014411cd4260826bcfa9168ae39f01 100644 (file)
@@ -42,8 +42,8 @@ UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
       // Generate a report for this bug.
       BugReport *R = new BugReport(*BT, BT->getName(), N);
       R->addRange(A->getIdx()->getSourceRange());
-      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, 
-                           A->getIdx());
+      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                                                 A->getIdx()));
       C.EmitReport(R);
     }
   }
index 6f937c6816a35112aefd07ed53e29cf0d388e8d4..b0c4bee424f300310bcb0a5191191451e56ea6bd 100644 (file)
@@ -77,7 +77,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
   BugReport *R = new BugReport(*BT, str, N);
   if (ex) {
     R->addRange(ex->getSourceRange());
-    R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
+    R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex));
   }
   C.EmitReport(R);
 }
index f6931fc09f08e4dee53c1b9fa7748119875a46fc..336df59bd8d7315654ab63b4541233fa2e28204d 100644 (file)
@@ -206,8 +206,8 @@ void UnixAPIChecker::CheckMallocZero(CheckerContext &C,
       new BugReport(*BT_mallocZero, "Call to 'malloc' has an allocation"
                                             " size of 0 bytes", N);
     report->addRange(CE->getArg(0)->getSourceRange());
-    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                              CE->getArg(0));
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
+                                                                CE->getArg(0)));
     C.EmitReport(report);
     return;
   }
index 61590b296a2b68b71c8f9d9d28603db8511f09c3..b34b97c5b301b550c365380a17c5c948cea4a182 100644 (file)
@@ -65,7 +65,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
     BugReport *report =
       new BugReport(*BT_undef, BT_undef->getName(), N);
     report->addRange(SE->getSourceRange());
-    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, SE));
     C.EmitReport(report);
     return;
   }
@@ -90,7 +90,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
     BugReport *report =
       new BugReport(*BT_zero, BT_zero->getName(), N);
     report->addRange(SE->getSourceRange());
-    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, SE));
     C.EmitReport(report);
     return;
   }
index 6821806c8467715e4b8c1e921866f5a2395f13f9..fb0331c274547c8faac5e6da93d5b8716f60f2a7 100644 (file)
@@ -1672,8 +1672,8 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
     return;
 
   // Register additional node visitors.
-  bugreporter::registerNilReceiverVisitor(*R);
-  bugreporter::registerConditionVisitor(*R);
+  R->addVisitor(new NilReceiverBRVisitor());
+  R->addVisitor(new ConditionBRVisitor());
 
   switch (PDB.getGenerationScheme()) {
     case PathDiagnosticClient::Extensive:
index b6e726fd0be5968b61bc9cd22708dc9838a798f9..9fbccf8f8136cd88bcef8cdd116e872f56227576 100644 (file)
@@ -11,6 +11,7 @@
 //  enhance the diagnostics reported for a bug.
 //
 //===----------------------------------------------------------------------===//
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
 
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
@@ -71,249 +72,213 @@ const Stmt *bugreporter::GetRetValExpr(const ExplodedNode *N) {
 //===----------------------------------------------------------------------===//
 // Definitions for bug reporter visitors.
 //===----------------------------------------------------------------------===//
+void FindLastStoreBRVisitor ::Profile(llvm::FoldingSetNodeID &ID) const {
+  static int tag = 0;
+  ID.AddPointer(&tag);
+  ID.AddPointer(R);
+  ID.Add(V);
+}
 
-namespace {
-class FindLastStoreBRVisitor : public BugReporterVisitor {
-  const MemRegion *R;
-  SVal V;
-  bool satisfied;
-  const ExplodedNode *StoreSite;
-public:
-  FindLastStoreBRVisitor(SVal v, const MemRegion *r)
-  : R(r), V(v), satisfied(false), StoreSite(0) {}
-
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
-    static int tag = 0;
-    ID.AddPointer(&tag);
-    ID.AddPointer(R);
-    ID.Add(V);
-  }
-
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) {
-
-    if (satisfied)
-      return NULL;
-
-    if (!StoreSite) {
-      const ExplodedNode *Node = N, *Last = NULL;
+PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *N,
+                                                     const ExplodedNode *PrevN,
+                                                     BugReporterContext &BRC,
+                                                     BugReport &BR) {
 
-      for ( ; Node ; Last = Node, Node = Node->getFirstPred()) {
+  if (satisfied)
+    return NULL;
 
-        if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
-          if (const PostStmt *P = Node->getLocationAs<PostStmt>())
-            if (const DeclStmt *DS = P->getStmtAs<DeclStmt>())
-              if (DS->getSingleDecl() == VR->getDecl()) {
-                Last = Node;
-                break;
-              }
-        }
+  if (!StoreSite) {
+    const ExplodedNode *Node = N, *Last = NULL;
 
-        if (Node->getState()->getSVal(R) != V)
-          break;
-      }
+    for ( ; Node ; Last = Node, Node = Node->getFirstPred()) {
 
-      if (!Node || !Last) {
-        satisfied = true;
-        return NULL;
+      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+        if (const PostStmt *P = Node->getLocationAs<PostStmt>())
+          if (const DeclStmt *DS = P->getStmtAs<DeclStmt>())
+            if (DS->getSingleDecl() == VR->getDecl()) {
+              Last = Node;
+              break;
+            }
       }
 
-      StoreSite = Last;
+      if (Node->getState()->getSVal(R) != V)
+        break;
     }
 
-    if (StoreSite != N)
+    if (!Node || !Last) {
+      satisfied = true;
       return NULL;
+    }
 
-    satisfied = true;
-    llvm::SmallString<256> sbuf;
-    llvm::raw_svector_ostream os(sbuf);
+    StoreSite = Last;
+  }
 
-    if (const PostStmt *PS = N->getLocationAs<PostStmt>()) {
-      if (const DeclStmt *DS = PS->getStmtAs<DeclStmt>()) {
+  if (StoreSite != N)
+    return NULL;
 
-        if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
-          os << "Variable '" << VR->getDecl() << "' ";
-        }
-        else
-          return NULL;
-
-        if (isa<loc::ConcreteInt>(V)) {
-          bool b = false;
-          if (R->isBoundable()) {
-            if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
-              if (TR->getValueType()->isObjCObjectPointerType()) {
-                os << "initialized to nil";
-                b = true;
-              }
-            }
-          }
+  satisfied = true;
+  llvm::SmallString<256> sbuf;
+  llvm::raw_svector_ostream os(sbuf);
 
-          if (!b)
-            os << "initialized to a null pointer value";
-        }
-        else if (isa<nonloc::ConcreteInt>(V)) {
-          os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
-        }
-        else if (V.isUndef()) {
-          if (isa<VarRegion>(R)) {
-            const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
-            if (VD->getInit())
-              os << "initialized to a garbage value";
-            else
-              os << "declared without an initial value";
-          }
-        }
+  if (const PostStmt *PS = N->getLocationAs<PostStmt>()) {
+    if (const DeclStmt *DS = PS->getStmtAs<DeclStmt>()) {
+
+      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+        os << "Variable '" << VR->getDecl() << "' ";
       }
-    }
+      else
+        return NULL;
 
-    if (os.str().empty()) {
       if (isa<loc::ConcreteInt>(V)) {
         bool b = false;
         if (R->isBoundable()) {
           if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
             if (TR->getValueType()->isObjCObjectPointerType()) {
-              os << "nil object reference stored to ";
+              os << "initialized to nil";
               b = true;
             }
           }
         }
 
         if (!b)
-          os << "Null pointer value stored to ";
-      }
-      else if (V.isUndef()) {
-        os << "Uninitialized value stored to ";
+          os << "initialized to a null pointer value";
       }
       else if (isa<nonloc::ConcreteInt>(V)) {
-        os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
-           << " is assigned to ";
+        os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
       }
-      else
-        return NULL;
-
-      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
-        os << '\'' << VR->getDecl() << '\'';
+      else if (V.isUndef()) {
+        if (isa<VarRegion>(R)) {
+          const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
+          if (VD->getInit())
+            os << "initialized to a garbage value";
+          else
+            os << "declared without an initial value";
+        }
       }
-      else
-        return NULL;
     }
+  }
 
-    // FIXME: Refactor this into BugReporterContext.
-    const Stmt *S = 0;
-    ProgramPoint P = N->getLocation();
+  if (os.str().empty()) {
+    if (isa<loc::ConcreteInt>(V)) {
+      bool b = false;
+      if (R->isBoundable()) {
+        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
+          if (TR->getValueType()->isObjCObjectPointerType()) {
+            os << "nil object reference stored to ";
+            b = true;
+          }
+        }
+      }
 
-    if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
-      const CFGBlock *BSrc = BE->getSrc();
-      S = BSrc->getTerminatorCondition();
+      if (!b)
+        os << "Null pointer value stored to ";
     }
-    else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
-      S = PS->getStmt();
+    else if (V.isUndef()) {
+      os << "Uninitialized value stored to ";
     }
-
-    if (!S)
+    else if (isa<nonloc::ConcreteInt>(V)) {
+      os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
+               << " is assigned to ";
+    }
+    else
       return NULL;
 
-    // Construct a new PathDiagnosticPiece.
-    PathDiagnosticLocation L(S, BRC.getSourceManager());
-    return new PathDiagnosticEventPiece(L, os.str());
+    if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+      os << '\'' << VR->getDecl() << '\'';
+    }
+    else
+      return NULL;
   }
-};
 
+  // FIXME: Refactor this into BugReporterContext.
+  const Stmt *S = 0;
+  ProgramPoint P = N->getLocation();
 
-static void registerFindLastStore(BugReport &BR, const MemRegion *R,
-                                  SVal V) {
-  BR.addVisitor(new FindLastStoreBRVisitor(V, R));
-}
-
-class TrackConstraintBRVisitor : public BugReporterVisitor {
-  DefinedSVal Constraint;
-  const bool Assumption;
-  bool isSatisfied;
-public:
-  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
-  : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) const {
-    static int tag = 0;
-    ID.AddPointer(&tag);
-    ID.AddBoolean(Assumption);
-    ID.Add(Constraint);
+  if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+    const CFGBlock *BSrc = BE->getSrc();
+    S = BSrc->getTerminatorCondition();
+  }
+  else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+    S = PS->getStmt();
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) {
-    if (isSatisfied)
-      return NULL;
+  if (!S)
+    return NULL;
 
-    // Check if in the previous state it was feasible for this constraint
-    // to *not* be true.
-    if (PrevN->getState()->assume(Constraint, !Assumption)) {
+  // Construct a new PathDiagnosticPiece.
+  PathDiagnosticLocation L(S, BRC.getSourceManager());
+  return new PathDiagnosticEventPiece(L, os.str());
+}
 
-      isSatisfied = true;
+void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
+  static int tag = 0;
+  ID.AddPointer(&tag);
+  ID.AddBoolean(Assumption);
+  ID.Add(Constraint);
+}
 
-      // As a sanity check, make sure that the negation of the constraint
-      // was infeasible in the current state.  If it is feasible, we somehow
-      // missed the transition point.
-      if (N->getState()->assume(Constraint, !Assumption))
-        return NULL;
+PathDiagnosticPiece *
+TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
+                                    const ExplodedNode *PrevN,
+                                    BugReporterContext &BRC,
+                                    BugReport &BR) {
+  if (isSatisfied)
+    return NULL;
 
-      // We found the transition point for the constraint.  We now need to
-      // pretty-print the constraint. (work-in-progress)
-      std::string sbuf;
-      llvm::raw_string_ostream os(sbuf);
+  // Check if in the previous state it was feasible for this constraint
+  // to *not* be true.
+  if (PrevN->getState()->assume(Constraint, !Assumption)) {
 
-      if (isa<Loc>(Constraint)) {
-        os << "Assuming pointer value is ";
-        os << (Assumption ? "non-null" : "null");
-      }
+    isSatisfied = true;
 
-      if (os.str().empty())
-        return NULL;
+    // As a sanity check, make sure that the negation of the constraint
+    // was infeasible in the current state.  If it is feasible, we somehow
+    // missed the transition point.
+    if (N->getState()->assume(Constraint, !Assumption))
+      return NULL;
 
-      // FIXME: Refactor this into BugReporterContext.
-      const Stmt *S = 0;
-      ProgramPoint P = N->getLocation();
+    // We found the transition point for the constraint.  We now need to
+    // pretty-print the constraint. (work-in-progress)
+    std::string sbuf;
+    llvm::raw_string_ostream os(sbuf);
 
-      if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
-        const CFGBlock *BSrc = BE->getSrc();
-        S = BSrc->getTerminatorCondition();
-      }
-      else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
-        S = PS->getStmt();
-      }
+    if (isa<Loc>(Constraint)) {
+      os << "Assuming pointer value is ";
+      os << (Assumption ? "non-null" : "null");
+    }
 
-      if (!S)
-        return NULL;
+    if (os.str().empty())
+      return NULL;
+
+    // FIXME: Refactor this into BugReporterContext.
+    const Stmt *S = 0;
+    ProgramPoint P = N->getLocation();
 
-      // Construct a new PathDiagnosticPiece.
-      PathDiagnosticLocation L(S, BRC.getSourceManager());
-      return new PathDiagnosticEventPiece(L, os.str());
+    if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      const CFGBlock *BSrc = BE->getSrc();
+      S = BSrc->getTerminatorCondition();
+    }
+    else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+      S = PS->getStmt();
     }
 
-    return NULL;
+    if (!S)
+      return NULL;
+
+    // Construct a new PathDiagnosticPiece.
+    PathDiagnosticLocation L(S, BRC.getSourceManager());
+    return new PathDiagnosticEventPiece(L, os.str());
   }
-};
-} // end anonymous namespace
 
-static void registerTrackConstraint(BugReport &BR,
-                                    DefinedSVal Constraint,
-                                    bool Assumption) {
-  BR.addVisitor(new TrackConstraintBRVisitor(Constraint, Assumption));
+  return NULL;
 }
 
-void bugreporter::registerTrackNullOrUndefValue(BugReport &BR,
-                                                const void *data) {
-
-  const Stmt *S = static_cast<const Stmt*>(data);
-  const ExplodedNode *N = BR.getErrorNode();
+BugReporterVisitor *
+bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
+                                             const Stmt *S) {
+  if (!S || !N)
+    return 0;
 
-  if (!S)
-    return;
-  
   ProgramStateManager &StateMgr = N->getState()->getStateManager();
 
   // Walk through nodes until we get one that matches the statement
@@ -328,7 +293,7 @@ void bugreporter::registerTrackNullOrUndefValue(BugReport &BR,
   }
 
   if (!N)
-    return;
+    return 0;
   
   const ProgramState *state = N->getState();
 
@@ -343,7 +308,7 @@ void bugreporter::registerTrackNullOrUndefValue(BugReport &BR,
 
       if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)
           || V.isUndef()) {
-        ::registerFindLastStore(BR, R, V);
+        return new FindLastStoreBRVisitor(V, R);
       }
     }
   }
@@ -363,87 +328,64 @@ void bugreporter::registerTrackNullOrUndefValue(BugReport &BR,
 
     if (R) {
       assert(isa<SymbolicRegion>(R));
-      registerTrackConstraint(BR, loc::MemRegionVal(R), false);
+      return new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
     }
   }
-}
-
-void bugreporter::registerFindLastStore(BugReport &BR,
-                                        const void *data) {
 
-  const MemRegion *R = static_cast<const MemRegion*>(data);
-  const ExplodedNode *N = BR.getErrorNode();
+  return 0;
+}
 
-  if (!R)
-    return;
+BugReporterVisitor *
+FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
+                                            const MemRegion *R) {
+  assert(R && "The memory region is null.");
 
   const ProgramState *state = N->getState();
   SVal V = state->getSVal(R);
-
   if (V.isUnknown())
-    return;
+    return 0;
 
-  BR.addVisitor(new FindLastStoreBRVisitor(V, R));
+  return new FindLastStoreBRVisitor(V, R);
 }
 
 
-namespace {
-class NilReceiverVisitor : public BugReporterVisitor {
-public:
-  NilReceiverVisitor() {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) const {
-    static int x = 0;
-    ID.AddPointer(&x);
-  }
-
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) {
-
-    const PostStmt *P = N->getLocationAs<PostStmt>();
-    if (!P)
-      return 0;
-    const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
-    if (!ME)
-      return 0;
-    const Expr *Receiver = ME->getInstanceReceiver();
-    if (!Receiver)
-      return 0;
-    const ProgramState *state = N->getState();
-    const SVal &V = state->getSVal(Receiver);
-    const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
-    if (!DV)
-      return 0;
-    state = state->assume(*DV, true);
-    if (state)
-      return 0;
-
-    // The receiver was nil, and hence the method was skipped.
-    // Register a BugReporterVisitor to issue a message telling us how
-    // the receiver was null.
-    bugreporter::registerTrackNullOrUndefValue(BR, Receiver);
-    // Issue a message saying that the method was skipped.
-    PathDiagnosticLocation L(Receiver, BRC.getSourceManager());
-    return new PathDiagnosticEventPiece(L, "No method actually called "
-                                           "because the receiver is nil");
-  }
-};
-} // end anonymous namespace
+PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
+                                                     const ExplodedNode *PrevN,
+                                                     BugReporterContext &BRC,
+                                                     BugReport &BR) {
+  const PostStmt *P = N->getLocationAs<PostStmt>();
+  if (!P)
+    return 0;
+  const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
+  if (!ME)
+    return 0;
+  const Expr *Receiver = ME->getInstanceReceiver();
+  if (!Receiver)
+    return 0;
+  const ProgramState *state = N->getState();
+  const SVal &V = state->getSVal(Receiver);
+  const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
+  if (!DV)
+    return 0;
+  state = state->assume(*DV, true);
+  if (state)
+    return 0;
 
-void bugreporter::registerNilReceiverVisitor(BugReport &BR) {
-  BR.addVisitor(new NilReceiverVisitor());
+  // The receiver was nil, and hence the method was skipped.
+  // Register a BugReporterVisitor to issue a message telling us how
+  // the receiver was null.
+  BR.addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Receiver));
+  // Issue a message saying that the method was skipped.
+  PathDiagnosticLocation L(Receiver, BRC.getSourceManager());
+  return new PathDiagnosticEventPiece(L, "No method actually called "
+      "because the receiver is nil");
 }
 
 // Registers every VarDecl inside a Stmt with a last store visitor.
-void bugreporter::registerVarDeclsLastStore(BugReport &BR,
-                                            const void *stmt) {
-  const Stmt *S = static_cast<const Stmt *>(stmt);
+void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
+                                                       const Stmt *S) {
   const ExplodedNode *N = BR.getErrorNode();
-
   std::deque<const Stmt *> WorkList;
-
   WorkList.push_back(S);
 
   while (!WorkList.empty()) {
@@ -462,7 +404,8 @@ void bugreporter::registerVarDeclsLastStore(BugReport &BR,
         SVal V = state->getSVal(S);
 
         if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) {
-          ::registerFindLastStore(BR, R, V);
+          // Register a new visitor with the BugReport.
+          BR.addVisitor(new FindLastStoreBRVisitor(V, R));
         }
       }
     }
@@ -476,51 +419,10 @@ void bugreporter::registerVarDeclsLastStore(BugReport &BR,
 //===----------------------------------------------------------------------===//
 // Visitor that tries to report interesting diagnostics from conditions.
 //===----------------------------------------------------------------------===//
-
-namespace {
-class ConditionVisitor : public BugReporterVisitor {
-public:
-  void Profile(llvm::FoldingSetNodeID &ID) const {
-    static int x = 0;
-    ID.AddPointer(&x);
-  }
-
-  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                         const ExplodedNode *Prev,
-                                         BugReporterContext &BRC,
-                                         BugReport &BR);
-  
-  PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
-                                       const ProgramState *CurrentState,
-                                       const ProgramState *PrevState,
-                                       const CFGBlock *srcBlk,
-                                       const CFGBlock *dstBlk,
-                                       BugReporterContext &BRC);
-  
-  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
-                                     bool tookTrue,
-                                     BugReporterContext &BRC);
-
-  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
-                                     const DeclRefExpr *DR,
-                                     const bool tookTrue,
-                                     BugReporterContext &BRC);
-  
-  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
-                                     const BinaryOperator *BExpr,
-                                     const bool tookTrue,
-                                     BugReporterContext &BRC);
-  
-  bool patternMatch(const Expr *Ex,
-                    llvm::raw_ostream &Out,
-                    BugReporterContext &BRC);
-};
-}
-
-PathDiagnosticPiece *ConditionVisitor::VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *Prev,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) {
+PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *Prev,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) {
   
   const ProgramPoint &progPoint = N->getLocation();
 
@@ -564,13 +466,12 @@ PathDiagnosticPiece *ConditionVisitor::VisitNode(const ExplodedNode *N,
 }
 
 PathDiagnosticPiece *
-ConditionVisitor::VisitTerminator(const Stmt *Term,
-                                  const ProgramState *CurrentState,
-                                  const ProgramState *PrevState,
-                                  const CFGBlock *srcBlk,
-                                  const CFGBlock *dstBlk,
-                                  BugReporterContext &BRC) {
-
+ConditionBRVisitor::VisitTerminator(const Stmt *Term,
+                                    const ProgramState *CurrentState,
+                                    const ProgramState *PrevState,
+                                    const CFGBlock *srcBlk,
+                                    const CFGBlock *dstBlk,
+                                    BugReporterContext &BRC) {
   const Expr *Cond = 0;
   
   switch (Term->getStmtClass()) {
@@ -592,9 +493,9 @@ ConditionVisitor::VisitTerminator(const Stmt *Term,
 }
 
 PathDiagnosticPiece *
-ConditionVisitor::VisitTrueTest(const Expr *Cond,
-                                bool tookTrue,
-                                BugReporterContext &BRC) {
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
+                                  bool tookTrue,
+                                  BugReporterContext &BRC) {
   
   const Expr *Ex = Cond;
   
@@ -620,8 +521,8 @@ ConditionVisitor::VisitTrueTest(const Expr *Cond,
   }
 }
 
-bool ConditionVisitor::patternMatch(const Expr *Ex, llvm::raw_ostream &Out,
-                                    BugReporterContext &BRC) {
+bool ConditionBRVisitor::patternMatch(const Expr *Ex, llvm::raw_ostream &Out,
+                                      BugReporterContext &BRC) {
   const Expr *OriginalExpr = Ex;
   Ex = Ex->IgnoreParenCasts();
 
@@ -658,10 +559,10 @@ bool ConditionVisitor::patternMatch(const Expr *Ex, llvm::raw_ostream &Out,
 }
 
 PathDiagnosticPiece *
-ConditionVisitor::VisitTrueTest(const Expr *Cond,
-                                const BinaryOperator *BExpr,
-                                const bool tookTrue,
-                                BugReporterContext &BRC) {
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
+                                  const BinaryOperator *BExpr,
+                                  const bool tookTrue,
+                                  BugReporterContext &BRC) {
   
   bool shouldInvert = false;
   
@@ -726,10 +627,10 @@ ConditionVisitor::VisitTrueTest(const Expr *Cond,
 }
   
 PathDiagnosticPiece *
-ConditionVisitor::VisitTrueTest(const Expr *Cond,
-                                const DeclRefExpr *DR,
-                                const bool tookTrue,
-                                BugReporterContext &BRC) {
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
+                                  const DeclRefExpr *DR,
+                                  const bool tookTrue,
+                                  BugReporterContext &BRC) {
 
   const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
   if (!VD)
@@ -756,8 +657,3 @@ ConditionVisitor::VisitTrueTest(const Expr *Cond,
   PathDiagnosticLocation Loc(Cond, BRC.getSourceManager());
   return new PathDiagnosticEventPiece(Loc, Out.str());
 }
-
-void bugreporter::registerConditionVisitor(BugReport &BR) {
-  BR.addVisitor(new ConditionVisitor());
-}
-