[cfe-commits] r58440 - /cfe/trunk/lib/Analysis/GRExprEngine.cpp

Zhongxing Xu xuzhongxing at gmail.com
Thu Oct 30 19:56:59 PDT 2008


On Fri, Oct 31, 2008 at 1:47 AM, Ted Kremenek <kremenek at apple.com> 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()) {
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20081031/477b9f0f/attachment.html>


More information about the cfe-commits mailing list