]> granicus.if.org Git - clang/commitdiff
UndefBranchChecker: more bug reporter helper information emit.
authorZhongxing Xu <xuzhongxing@gmail.com>
Mon, 23 Nov 2009 03:29:59 +0000 (03:29 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Mon, 23 Nov 2009 03:29:59 +0000 (03:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89643 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/GRExprEngineInternalChecks.cpp
lib/Analysis/UndefBranchChecker.cpp

index d5fe20019d48a065889933661003e9eddf8d4db5..62c361ca5581887c52533fc722ba216252caa349 100644 (file)
@@ -204,96 +204,6 @@ public:
   }
 };
 
-class VISIBILITY_HIDDEN ArgReport : public BuiltinBugReport {
-  const Stmt *Arg;
-public:
-  ArgReport(BugType& bt, const char* desc, ExplodedNode *n,
-         const Stmt *arg)
-  : BuiltinBugReport(bt, desc, n), Arg(arg) {}
-
-  ArgReport(BugType& bt, const char *shortDesc, const char *desc,
-                   ExplodedNode *n, const Stmt *arg)
-  : BuiltinBugReport(bt, shortDesc, desc, n), Arg(arg) {}
-
-  const Stmt *getArg() const { return Arg; }
-};
-
-class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
-  struct VISIBILITY_HIDDEN FindUndefExpr {
-    GRStateManager& VM;
-    const GRState* St;
-
-    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
-
-    Expr* FindExpr(Expr* Ex) {
-      if (!MatchesCriteria(Ex))
-        return 0;
-
-      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
-        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
-          Expr* E2 = FindExpr(ExI);
-          if (E2) return E2;
-        }
-
-      return Ex;
-    }
-
-    bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
-  };
-
-public:
-  UndefBranch(GRExprEngine *eng)
-    : BuiltinBug(eng,"Use of garbage value",
-                 "Branch condition evaluates to an undefined or garbage value")
-       {}
-
-  void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
-    for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
-         E=Eng.undef_branches_end(); I!=E; ++I) {
-
-      // What's going on here: we want to highlight the subexpression of the
-      // condition that is the most likely source of the "uninitialized
-      // branch condition."  We do a recursive walk of the condition's
-      // subexpressions and roughly look for the most nested subexpression
-      // that binds to Undefined.  We then highlight that expression's range.
-      BlockEdge B = cast<BlockEdge>((*I)->getLocation());
-      Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
-      assert (Ex && "Block must have a terminator.");
-
-      // Get the predecessor node and check if is a PostStmt with the Stmt
-      // being the terminator condition.  We want to inspect the state
-      // of that node instead because it will contain main information about
-      // the subexpressions.
-      assert (!(*I)->pred_empty());
-
-      // Note: any predecessor will do.  They should have identical state,
-      // since all the BlockEdge did was act as an error sink since the value
-      // had to already be undefined.
-      ExplodedNode *N = *(*I)->pred_begin();
-      ProgramPoint P = N->getLocation();
-      const GRState* St = (*I)->getState();
-
-      if (PostStmt* PS = dyn_cast<PostStmt>(&P))
-        if (PS->getStmt() == Ex)
-          St = N->getState();
-
-      FindUndefExpr FindIt(Eng.getStateManager(), St);
-      Ex = FindIt.FindExpr(Ex);
-
-      ArgReport *R = new ArgReport(*this, desc.c_str(), *I, Ex);
-      R->addRange(Ex->getSourceRange());
-      BR.EmitReport(R);
-    }
-  }
-
-  void registerInitialVisitors(BugReporterContext& BRC,
-                               const ExplodedNode* N,
-                               BuiltinBugReport *R) {
-    registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
-                                  N);
-  }
-};
-
 } // end clang namespace
 
 //===----------------------------------------------------------------------===//
index 38cd107a9d98ced051006e03fae2ef29a4493779..8d72b5a96be2b06c76a6d26658bdfbded0c4ba69 100644 (file)
@@ -21,6 +21,29 @@ namespace {
 
 class VISIBILITY_HIDDEN UndefBranchChecker : public Checker {
   BuiltinBug *BT;
+
+  struct VISIBILITY_HIDDEN FindUndefExpr {
+    GRStateManager& VM;
+    const GRState* St;
+
+    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
+
+    Expr* FindExpr(Expr* Ex) {
+      if (!MatchesCriteria(Ex))
+        return 0;
+
+      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
+        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
+          Expr* E2 = FindExpr(ExI);
+          if (E2) return E2;
+        }
+
+      return Ex;
+    }
+
+    bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
+  };
+
 public:
   UndefBranchChecker() : BT(0) {}
   static void *getTag();
@@ -54,6 +77,37 @@ void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder,
       EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getDescription(),N);
       R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, 
                            Condition);
+
+      // What's going on here: we want to highlight the subexpression of the
+      // condition that is the most likely source of the "uninitialized
+      // branch condition."  We do a recursive walk of the condition's
+      // subexpressions and roughly look for the most nested subexpression
+      // that binds to Undefined.  We then highlight that expression's range.
+      BlockEdge B = cast<BlockEdge>(N->getLocation());
+      Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
+      assert (Ex && "Block must have a terminator.");
+
+      // Get the predecessor node and check if is a PostStmt with the Stmt
+      // being the terminator condition.  We want to inspect the state
+      // of that node instead because it will contain main information about
+      // the subexpressions.
+      assert (!N->pred_empty());
+
+      // Note: any predecessor will do.  They should have identical state,
+      // since all the BlockEdge did was act as an error sink since the value
+      // had to already be undefined.
+      ExplodedNode *PrevN = *N->pred_begin();
+      ProgramPoint P = PrevN->getLocation();
+      const GRState* St = N->getState();
+
+      if (PostStmt* PS = dyn_cast<PostStmt>(&P))
+        if (PS->getStmt() == Ex)
+          St = PrevN->getState();
+
+      FindUndefExpr FindIt(Eng.getStateManager(), St);
+      Ex = FindIt.FindExpr(Ex);
+      R->addRange(Ex->getSourceRange());
+
       Eng.getBugReporter().EmitReport(R);
     }