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,
|
void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,
|
||||||
NodeSet& Dst) {
|
NodeSet& Dst) {
|
||||||
const GRState* state = GetState(Pred);
|
const GRState* state = GetState(Pred);
|
||||||
|
@ -1627,36 +1643,49 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,
|
||||||
|
|
||||||
unsigned NumInitElements = E->getNumInits();
|
unsigned NumInitElements = E->getNumInits();
|
||||||
|
|
||||||
llvm::SmallVector<SVal, 10> InitVals;
|
|
||||||
InitVals.reserve(NumInitElements);
|
|
||||||
|
|
||||||
|
|
||||||
if (T->isArrayType() || T->isStructureType()) {
|
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;
|
NodeSet Tmp;
|
||||||
Visit(Init, Pred, Tmp);
|
Visit(*X.Itr, X.N, Tmp);
|
||||||
|
|
||||||
// FIXME: Use worklist to allow state splitting.
|
InitListExpr::reverse_iterator NewItr = X.Itr + 1;
|
||||||
assert(Tmp.size() == 1);
|
|
||||||
|
|
||||||
// Get the new intermediate node and its state.
|
for (NodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
|
||||||
Pred = *Tmp.begin();
|
// Get the last initializer value.
|
||||||
state = GetState(Pred);
|
state = GetState(*NI);
|
||||||
|
SVal InitV = GetSVal(state, cast<Expr>(*X.Itr));
|
||||||
|
|
||||||
SVal InitV = GetSVal(state, Init);
|
// Construct the new list of values by prepending the new value to
|
||||||
InitVals.push_back(InitV);
|
// the already constructed list.
|
||||||
}
|
llvm::ImmutableList<SVal> NewVals =
|
||||||
|
getBasicVals().consVals(InitV, X.Vals);
|
||||||
|
|
||||||
// Now we have a vector holding all init values. Make CompoundSValData.
|
if (NewItr == ItrEnd) {
|
||||||
SVal V = NonLoc::MakeCompoundVal(T, &InitVals[0], NumInitElements,
|
// Now we have a list holding all init values. Make CompoundSValData.
|
||||||
StateMgr.getBasicVals());
|
SVal V = NonLoc::MakeCompoundVal(T, NewVals, getBasicVals());
|
||||||
|
|
||||||
// Make final state and node.
|
// Make final state and node.
|
||||||
state = BindExpr(state, E, V);
|
MakeNode(Dst, E, Pred, BindExpr(state, E, V));
|
||||||
|
}
|
||||||
MakeNode(Dst, E, Pred, state);
|
else {
|
||||||
return;
|
// Still some initializer values to go. Push them onto the worklist.
|
||||||
|
WorkList.push_back(InitListWLItem(*NI, NewVals, NewItr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Loc::IsLocType(T) || T->isIntegerType()) {
|
if (Loc::IsLocType(T) || T->isIntegerType()) {
|
||||||
|
|
Loading…
Reference in New Issue