Remove a recursive visitation in ExprEngine that is no longer needed because the CFG is fully linearized.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152007 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index b7c4958..6016ee1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -258,16 +258,6 @@
 
   /// VisitAsmStmt - Transfer function logic for inline asm.
   void VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
-  void VisitAsmStmtHelperOutputs(const AsmStmt *A,
-                                 AsmStmt::const_outputs_iterator I,
-                                 AsmStmt::const_outputs_iterator E,
-                                 ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
-  void VisitAsmStmtHelperInputs(const AsmStmt *A,
-                                AsmStmt::const_inputs_iterator I,
-                                AsmStmt::const_inputs_iterator E,
-                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
   
   /// VisitBlockExpr - Transfer function logic for BlockExprs.
   void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 0a72f01..7528b4a 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1642,67 +1642,29 @@
 }
 
 void ExprEngine::VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred,
-                                ExplodedNodeSet &Dst) {
-  VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
-}
+                              ExplodedNodeSet &Dst) {
+  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
+  // We have processed both the inputs and the outputs.  All of the outputs
+  // should evaluate to Locs.  Nuke all of their values.
 
-void ExprEngine::VisitAsmStmtHelperOutputs(const AsmStmt *A,
-                                             AsmStmt::const_outputs_iterator I,
-                                             AsmStmt::const_outputs_iterator E,
-                                     ExplodedNode *Pred, ExplodedNodeSet &Dst) {
-  if (I == E) {
-    VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
-    return;
+  // FIXME: Some day in the future it would be nice to allow a "plug-in"
+  // which interprets the inline asm and stores proper results in the
+  // outputs.
+
+  ProgramStateRef state = Pred->getState();
+
+  for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
+       OE = A->end_outputs(); OI != OE; ++OI) {
+    SVal X = state->getSVal(*OI, Pred->getLocationContext());
+    assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
+
+    if (isa<Loc>(X))
+      state = state->bindLoc(cast<Loc>(X), UnknownVal());
   }
 
-  ExplodedNodeSet Tmp;
-  Visit(*I, Pred, Tmp);
-  ++I;
-
-  for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI)
-    VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
+  Bldr.generateNode(A, Pred, state);
 }
 
-void ExprEngine::VisitAsmStmtHelperInputs(const AsmStmt *A,
-                                            AsmStmt::const_inputs_iterator I,
-                                            AsmStmt::const_inputs_iterator E,
-                                            ExplodedNode *Pred,
-                                            ExplodedNodeSet &Dst) {
-  if (I == E) {
-    StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
-    // We have processed both the inputs and the outputs.  All of the outputs
-    // should evaluate to Locs.  Nuke all of their values.
-
-    // FIXME: Some day in the future it would be nice to allow a "plug-in"
-    // which interprets the inline asm and stores proper results in the
-    // outputs.
-
-    ProgramStateRef state = Pred->getState();
-
-    for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
-                                   OE = A->end_outputs(); OI != OE; ++OI) {
-
-      SVal X = state->getSVal(*OI, Pred->getLocationContext());
-      assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
-
-      if (isa<Loc>(X))
-        state = state->bindLoc(cast<Loc>(X), UnknownVal());
-    }
-
-    Bldr.generateNode(A, Pred, state);
-    return;
-  }
-
-  ExplodedNodeSet Tmp;
-  Visit(*I, Pred, Tmp);
-
-  ++I;
-
-  for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI!=NE; ++NI)
-    VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
-}
-
-
 //===----------------------------------------------------------------------===//
 // Visualization.
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp
index 89b4173..3f2bac1 100644
--- a/test/Analysis/nullptr.cpp
+++ b/test/Analysis/nullptr.cpp
@@ -50,3 +50,12 @@
   char **p = 0;
   delete *(p + 0); // expected-warning{{Dereference of null pointer}}
 }
+
+void zoo2() {
+  int **a = 0;
+  int **b = 0;
+  asm ("nop"
+      :"=a"(*a)
+      :"0"(*b) // expected-warning{{Dereference of null pointer}}
+      );
+}