Initial refactor of UndefBranchChecker. We still use GRBranchNodeBuilder
in the checker directly. But I don't have a better approach for now.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89640 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/UndefBranchChecker.cpp b/lib/Analysis/UndefBranchChecker.cpp
new file mode 100644
index 0000000..38cd107
--- /dev/null
+++ b/lib/Analysis/UndefBranchChecker.cpp
@@ -0,0 +1,63 @@
+//=== UndefBranchChecker.cpp -----------------------------------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines UndefBranchChecker, which checks for undefined branch
+// condition.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Analysis/PathSensitive/Checker.h"
+
+using namespace clang;
+
+namespace {
+
+class VISIBILITY_HIDDEN UndefBranchChecker : public Checker {
+  BuiltinBug *BT;
+public:
+  UndefBranchChecker() : BT(0) {}
+  static void *getTag();
+  void VisitBranchCondition(GRBranchNodeBuilder &Builder, GRExprEngine &Eng,
+                            Stmt *Condition, void *tag);
+};
+
+}
+
+void clang::RegisterUndefBranchChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UndefBranchChecker());
+}
+
+void *UndefBranchChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder, 
+                                              GRExprEngine &Eng,
+                                              Stmt *Condition, void *tag) {
+  const GRState *state = Builder.getState();
+  SVal X = state->getSVal(Condition);
+  if (X.isUndef()) {
+    ExplodedNode *N = Builder.generateNode(state, true);
+    if (N) {
+      N->markAsSink();
+      if (!BT)
+        BT = new BuiltinBug("Undefined branch",
+                 "Branch condition evaluates to an undefined or garbage value");
+      EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getDescription(),N);
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, 
+                           Condition);
+      Eng.getBugReporter().EmitReport(R);
+    }
+
+    Builder.markInfeasible(true);
+    Builder.markInfeasible(false);
+  }
+}