<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>