On Fri, Oct 31, 2008 at 1:47 AM, Ted Kremenek <[EMAIL PROTECTED]> wrote:
> Author: kremenek > Date: Thu Oct 30 12:47:32 2008 > New Revision: 58440 > > URL: http://llvm.org/viewvc/llvm-project?rev=58440&view=rev > Log: > Use a worklist in GRExprEngine::VisitInitListExpr to process > subexpressions. > > Modified: > cfe/trunk/lib/Analysis/GRExprEngine.cpp > > Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=58440&r1=58439&r2=58440&view=diff > > > ============================================================================== > --- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original) > +++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Oct 30 12:47:32 2008 > @@ -1619,44 +1619,73 @@ > } > } > > +namespace { > + // This class is used by VisitInitListExpr as an item in a worklist > + // for processing the values contained in an InitListExpr. > +class VISIBILITY_HIDDEN InitListWLItem { > +public: > + llvm::ImmutableList<SVal> Vals; > + GRExprEngine::NodeTy* N; > + InitListExpr::reverse_iterator Itr; > + > + InitListWLItem(GRExprEngine::NodeTy* n, llvm::ImmutableList<SVal> vals, > + InitListExpr::reverse_iterator itr) > + : Vals(vals), N(n), Itr(itr) {} > +}; > +} > + > + > void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred, > NodeSet& Dst) { > const GRState* state = GetState(Pred); > > QualType T = E->getType(); > > - unsigned NumInitElements = E->getNumInits(); > - > - llvm::SmallVector<SVal, 10> InitVals; > - InitVals.reserve(NumInitElements); > - > + unsigned NumInitElements = E->getNumInits(); > > if (T->isArrayType() || T->isStructureType()) { > - for (unsigned i = 0; i < NumInitElements; ++i) { > - Expr* Init = E->getInit(i); > - NodeSet Tmp; > - Visit(Init, Pred, Tmp); > - > - // FIXME: Use worklist to allow state splitting. > - assert(Tmp.size() == 1); > > - // Get the new intermediate node and its state. > - Pred = *Tmp.begin(); > - state = GetState(Pred); > > - SVal InitV = GetSVal(state, Init); > - InitVals.push_back(InitV); > - } > - > - // Now we have a vector holding all init values. Make > CompoundSValData. > - SVal V = NonLoc::MakeCompoundVal(T, &InitVals[0], NumInitElements, > - StateMgr.getBasicVals()); > + llvm::SmallVector<InitListWLItem, 10> WorkList; > + WorkList.reserve(NumInitElements); > + > + WorkList.push_back(InitListWLItem(Pred, > getBasicVals().getEmptySValList(), > + E->rbegin())); Hi Ted, Would visiting the InitList from right to left lead to some bugs? For example: int x = 3; int a[3] = {1, x = 1, 2*x+3}; At last a should be { 1, 1, 5 }. But visit from right to left results { 1, 1, 9 } > + > + InitListExpr::reverse_iterator ItrEnd = E->rend(); > + > + while (!WorkList.empty()) { > + InitListWLItem X = WorkList.back(); > + WorkList.pop_back(); > + > + NodeSet Tmp; > + Visit(*X.Itr, X.N, Tmp); > + > + InitListExpr::reverse_iterator NewItr = X.Itr + 1; > > - // Make final state and node. > - state = BindExpr(state, E, V); > + for (NodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) { > + // Get the last initializer value. > + state = GetState(*NI); > + SVal InitV = GetSVal(state, cast<Expr>(*X.Itr)); > + > + // Construct the new list of values by prepending the new value to > + // the already constructed list. > + llvm::ImmutableList<SVal> NewVals = > + getBasicVals().consVals(InitV, X.Vals); > + > + if (NewItr == ItrEnd) { > + // Now we have a list holding all init values. Make > CompoundSValData. > + SVal V = NonLoc::MakeCompoundVal(T, NewVals, getBasicVals()); > > - MakeNode(Dst, E, Pred, state); > - return; > + // Make final state and node. > + MakeNode(Dst, E, Pred, BindExpr(state, E, V)); > + } > + else { > + // Still some initializer values to go. Push them onto the > worklist. > + WorkList.push_back(InitListWLItem(*NI, NewVals, NewItr)); > + } > + } > + } > } > > if (Loc::IsLocType(T) || T->isIntegerType()) { > >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
