forked from OSchip/llvm-project
Use a worklist in GRExprEngine::VisitInitListExpr to process subexpressions.
llvm-svn: 58440
This commit is contained in:
parent
a2ace41aa3
commit
f68bf63611
|
@ -1619,6 +1619,22 @@ void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1627,36 +1643,49 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,
|
|||
|
||||
unsigned NumInitElements = E->getNumInits();
|
||||
|
||||
llvm::SmallVector<SVal, 10> InitVals;
|
||||
InitVals.reserve(NumInitElements);
|
||||
|
||||
|
||||
if (T->isArrayType() || T->isStructureType()) {
|
||||
for (unsigned i = 0; i < NumInitElements; ++i) {
|
||||
Expr* Init = E->getInit(i);
|
||||
|
||||
|
||||
llvm::SmallVector<InitListWLItem, 10> WorkList;
|
||||
WorkList.reserve(NumInitElements);
|
||||
|
||||
WorkList.push_back(InitListWLItem(Pred, getBasicVals().getEmptySValList(),
|
||||
E->rbegin()));
|
||||
|
||||
InitListExpr::reverse_iterator ItrEnd = E->rend();
|
||||
|
||||
while (!WorkList.empty()) {
|
||||
InitListWLItem X = WorkList.back();
|
||||
WorkList.pop_back();
|
||||
|
||||
NodeSet Tmp;
|
||||
Visit(Init, Pred, Tmp);
|
||||
Visit(*X.Itr, X.N, Tmp);
|
||||
|
||||
// FIXME: Use worklist to allow state splitting.
|
||||
assert(Tmp.size() == 1);
|
||||
InitListExpr::reverse_iterator NewItr = X.Itr + 1;
|
||||
|
||||
// Get the new intermediate node and its state.
|
||||
Pred = *Tmp.begin();
|
||||
state = GetState(Pred);
|
||||
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));
|
||||
|
||||
SVal InitV = GetSVal(state, Init);
|
||||
InitVals.push_back(InitV);
|
||||
}
|
||||
// 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);
|
||||
|
||||
// Now we have a vector holding all init values. Make CompoundSValData.
|
||||
SVal V = NonLoc::MakeCompoundVal(T, &InitVals[0], NumInitElements,
|
||||
StateMgr.getBasicVals());
|
||||
if (NewItr == ItrEnd) {
|
||||
// Now we have a list holding all init values. Make CompoundSValData.
|
||||
SVal V = NonLoc::MakeCompoundVal(T, NewVals, getBasicVals());
|
||||
|
||||
// Make final state and node.
|
||||
state = BindExpr(state, E, V);
|
||||
|
||||
MakeNode(Dst, E, Pred, state);
|
||||
return;
|
||||
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()) {
|
||||
|
|
Loading…
Reference in New Issue