From b9eda67380a7173af7e03f995540bf212dc0ec0a Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 30 Oct 2009 07:19:39 +0000 Subject: [PATCH] Fix PR5316: make assignment expressions can be visited as lvalue. Then we can get the correct base lvalue. Revert r85578. llvm-svn: 85579 --- .../Analysis/PathSensitive/GRExprEngine.h | 3 +- clang/lib/Analysis/GRExprEngine.cpp | 47 +++++++++---------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index e30b4271f1db..89ca337f15e7 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -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. diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 99e214400ecf..88e67981ac1e 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -388,11 +388,11 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { if (AMgr.shouldEagerlyAssume() && (B->isRelationalOp() || B->isEqualityOp())) { ExplodedNodeSet Tmp; - VisitBinaryOperator(cast(S), Pred, Tmp); + VisitBinaryOperator(cast(S), Pred, Tmp, false); EvalEagerlyAssume(Dst, Tmp, cast(S)); } else - VisitBinaryOperator(cast(S), Pred, Dst); + VisitBinaryOperator(cast(S), Pred, Dst, false); break; } @@ -414,7 +414,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { } case Stmt::CompoundAssignOperatorClass: - VisitBinaryOperator(cast(S), Pred, Dst); + VisitBinaryOperator(cast(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(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(&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; }