<br><br><div class="gmail_quote">On Fri, Oct 31, 2008 at 1:47 AM, Ted Kremenek <span dir="ltr"><<a href="mailto:kremenek@apple.com">kremenek@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Author: kremenek<br>
Date: Thu Oct 30 12:47:32 2008<br>
New Revision: 58440<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=58440&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=58440&view=rev</a><br>
Log:<br>
Use a worklist in GRExprEngine::VisitInitListExpr to process subexpressions.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Analysis/GRExprEngine.cpp<br>
<br>
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=58440&r1=58439&r2=58440&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=58440&r1=58439&r2=58440&view=diff</a><br>

<br>
==============================================================================<br>
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)<br>
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Oct 30 12:47:32 2008<br>
@@ -1619,44 +1619,73 @@<br>
   }<br>
 }<br>
<br>
+namespace {<br>
+  // This class is used by VisitInitListExpr as an item in a worklist<br>
+  // for processing the values contained in an InitListExpr.<br>
+class VISIBILITY_HIDDEN InitListWLItem {<br>
+public:<br>
+  llvm::ImmutableList<SVal> Vals;<br>
+  GRExprEngine::NodeTy* N;<br>
+  InitListExpr::reverse_iterator Itr;<br>
+<br>
+  InitListWLItem(GRExprEngine::NodeTy* n, llvm::ImmutableList<SVal> vals,<br>
+         InitListExpr::reverse_iterator itr)<br>
+  : Vals(vals), N(n), Itr(itr) {}<br>
+};<br>
+}<br>
+<br>
+<br>
 void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,<br>
                                      NodeSet& Dst) {<br>
   const GRState* state = GetState(Pred);<br>
<br>
   QualType T = E->getType();<br>
<br>
-  unsigned NumInitElements = E->getNumInits();<br>
-<br>
-  llvm::SmallVector<SVal, 10> InitVals;<br>
-  InitVals.reserve(NumInitElements);<br>
-<br>
+  unsigned NumInitElements = E->getNumInits();<br>
<br>
   if (T->isArrayType() || T->isStructureType()) {<br>
-    for (unsigned i = 0; i < NumInitElements; ++i) {<br>
-      Expr* Init = E->getInit(i);<br>
-      NodeSet Tmp;<br>
-      Visit(Init, Pred, Tmp);<br>
-<br>
-      // FIXME: Use worklist to allow state splitting.<br>
-      assert(Tmp.size() == 1);<br>
<br>
-      // Get the new intermediate node and its state.<br>
-      Pred = *Tmp.begin();<br>
-      state = GetState(Pred);<br>
<br>
-      SVal InitV = GetSVal(state, Init);<br>
-      InitVals.push_back(InitV);<br>
-    }<br>
-<br>
-    // Now we have a vector holding all init values. Make CompoundSValData.<br>
-    SVal V = NonLoc::MakeCompoundVal(T, &InitVals[0], NumInitElements,<br>
-                                     StateMgr.getBasicVals());<br>
+    llvm::SmallVector<InitListWLItem, 10> WorkList;<br>
+    WorkList.reserve(NumInitElements);<br>
+<br>
+    WorkList.push_back(InitListWLItem(Pred, getBasicVals().getEmptySValList(),<br>
+                              E->rbegin()));</blockquote><div><br>Hi Ted,<br><br>Would visiting the InitList from right to left lead to some bugs? For example:<br><br>int x = 3;<br>int a[3] = {1, x = 1, 2*x+3};<br><br>
At last a should be { 1, 1, 5 }. But visit from right to left results { 1, 1, 9 } <br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
+<br>
+    InitListExpr::reverse_iterator ItrEnd = E->rend();<br>
+<br>
+    while (!WorkList.empty()) {<br>
+      InitListWLItem X = WorkList.back();<br>
+      WorkList.pop_back();<br>
+<br>
+      NodeSet Tmp;<br>
+      Visit(*X.Itr, X.N, Tmp);<br>
+<br>
+      InitListExpr::reverse_iterator NewItr = X.Itr + 1;<br>
<br>
-    // Make final state and node.<br>
-    state = BindExpr(state, E, V);<br>
+      for (NodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {<br>
+        // Get the last initializer value.<br>
+        state = GetState(*NI);<br>
+        SVal InitV = GetSVal(state, cast<Expr>(*X.Itr));<br>
+<br>
+        // Construct the new list of values by prepending the new value to<br>
+        // the already constructed list.<br>
+        llvm::ImmutableList<SVal> NewVals =<br>
+          getBasicVals().consVals(InitV, X.Vals);<br>
+<br>
+        if (NewItr == ItrEnd) {<br>
+          // Now we have a list holding all init values. Make CompoundSValData.<br>
+          SVal V = NonLoc::MakeCompoundVal(T, NewVals, getBasicVals());<br>
<br>
-    MakeNode(Dst, E, Pred, state);<br>
-    return;<br>
+          // Make final state and node.<br>
+          MakeNode(Dst, E, Pred,  BindExpr(state, E, V));<br>
+        }<br>
+        else {<br>
+          // Still some initializer values to go.  Push them onto the worklist.<br>
+          WorkList.push_back(InitListWLItem(*NI, NewVals, NewItr));<br>
+        }<br>
+      }<br>
+    }<br>
   }<br>
<br>
   if (Loc::IsLocType(T) || T->isIntegerType()) {<br>
<br></blockquote></div><br><br>