Fix PR5316: make assignment expressions can be visited as lvalue. Then we
can get the correct base lvalue.
Revert r85578.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85579 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index e30b427..89ca337 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -433,7 +433,8 @@
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/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 99e2144..88e6798 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -388,11 +388,11 @@
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 @@
}
case Stmt::CompoundAssignOperatorClass:
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+ VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
break;
case Stmt::CompoundLiteralExprClass:
@@ -582,6 +582,11 @@
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 @@
// 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::VisitBinaryOperator(BinaryOperator* B,
ExplodedNode* Pred,
- ExplodedNodeSet& Dst) {
+ ExplodedNodeSet& Dst, bool asLValue) {
ExplodedNodeSet Tmp1;
Expr* LHS = B->getLHS()->IgnoreParens();
@@ -2732,10 +2723,16 @@
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;
}