Fix PR5316: make assignment expressions can be visited as lvalue. Then we

can get the correct base lvalue.
Revert r85578.

llvm-svn: 85579
This commit is contained in:
Zhongxing Xu 2009-10-30 07:19:39 +00:00
parent e96a30a531
commit b9eda67380
2 changed files with 24 additions and 26 deletions

View File

@ -433,7 +433,8 @@ protected:
ExplodedNode* Pred, ExplodedNodeSet& Dst);
/// VisitBinaryOperator - Transfer function logic for binary operators.
void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst);
void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue);
/// VisitCall - Transfer function for function calls.

View File

@ -388,11 +388,11 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
if (AMgr.shouldEagerlyAssume() && (B->isRelationalOp() || B->isEqualityOp())) {
ExplodedNodeSet Tmp;
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
}
else
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
break;
}
@ -414,7 +414,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
}
case Stmt::CompoundAssignOperatorClass:
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
break;
case Stmt::CompoundLiteralExprClass:
@ -582,6 +582,11 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
return;
}
case Stmt::BinaryOperatorClass:
case Stmt::CompoundAssignOperatorClass:
VisitBinaryOperator(cast<BinaryOperator>(Ex), Pred, Dst, true);
return;
default:
// Arbitrary subexpressions can return aggregate temporaries that
// can be used in a lvalue context. We need to enhance our support
@ -1092,26 +1097,12 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
// FIXME: Should we insert some assumption logic in here to determine
// if "Base" is a valid piece of memory? Before we put this assumption
// later when using FieldOffset lvals (which we no longer have).
SVal BaseV = state->getSVal(Base);
if (nonloc::LazyCompoundVal *LVC=dyn_cast<nonloc::LazyCompoundVal>(&BaseV)){
const LazyCompoundValData *D = LVC->getCVData();
const FieldRegion * FR =
getStateManager().getRegionManager().getFieldRegion(Field,
D->getRegion());
SVal L = state->getLValue(Field, state->getSVal(Base));
SVal V = D->getState()->getSVal(loc::MemRegionVal(FR));
MakeNode(Dst, M, *I, state->BindExpr(M, V));
}
else {
SVal L = state->getLValue(Field, BaseV);
if (asLValue)
MakeNode(Dst, M, *I, state->BindExpr(M, L),
ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, M, *I, state, L);
}
if (asLValue)
MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, M, *I, state, L);
}
}
@ -2686,7 +2677,7 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, ExplodedNode* Pred,
void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
ExplodedNode* Pred,
ExplodedNodeSet& Dst) {
ExplodedNodeSet& Dst, bool asLValue) {
ExplodedNodeSet Tmp1;
Expr* LHS = B->getLHS()->IgnoreParens();
@ -2732,10 +2723,16 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
unsigned Count = Builder->getCurrentBlockCount();
RightV = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), Count);
}
SVal ExprVal;
if (asLValue)
ExprVal = LeftV;
else
ExprVal = RightV;
// Simulate the effects of a "store": bind the value of the RHS
// to the L-Value represented by the LHS.
EvalStore(Dst, B, LHS, *I2, state->BindExpr(B, RightV), LeftV, RightV);
EvalStore(Dst, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV, RightV);
continue;
}