Added transfer functions for pre- and post- increment/decrement operators.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46300 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp
index 0a9c68a..0c827ba 100644
--- a/Analysis/GRConstants.cpp
+++ b/Analysis/GRConstants.cpp
@@ -213,7 +213,7 @@
RValue EvalSub(ValueManager& ValMgr, const RValue& RHS) const;
RValue EvalMul(ValueManager& ValMgr, const RValue& RHS) const;
- static RValue GetRValue(ValueManager& ValMgr, IntegerLiteral* S);
+ static RValue GetRValue(ValueManager& ValMgr, const llvm::APSInt& V);
// Implement isa<T> support.
static inline bool classof(const ExprValue* V) {
@@ -359,9 +359,8 @@
return M;
}
-RValue RValue::GetRValue(ValueManager& ValMgr, IntegerLiteral* S) {
- return RValueMayEqualSet(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(),
- S->getValue()));
+RValue RValue::GetRValue(ValueManager& ValMgr, const llvm::APSInt& V) {
+ return RValueMayEqualSet(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
}
//===----------------------------------------------------------------------===//
@@ -504,6 +503,8 @@
bool StateCleaned;
+ ASTContext* getContext() const { return ValMgr.getContext(); }
+
public:
GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL),
StmtEntryNode(NULL), CurrentStmt(NULL) {}
@@ -558,6 +559,9 @@
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
+ /// VisitUnaryOperator - Transfer function logic for unary operators.
+ void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
+
/// VisitBinaryOperator - Transfer function logic for binary operators.
void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
};
@@ -612,7 +616,7 @@
return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
case Stmt::IntegerLiteralClass:
- return RValue::GetRValue(ValMgr, cast<IntegerLiteral>(S));
+ return RValue::GetRValue(ValMgr, cast<IntegerLiteral>(S)->getValue());
case Stmt::ImplicitCastExprClass: {
ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
@@ -742,6 +746,75 @@
}
}
+void GRConstants::VisitUnaryOperator(UnaryOperator* U,
+ GRConstants::NodeTy* Pred,
+ GRConstants::NodeSet& Dst) {
+ NodeSet S1;
+ Visit(U->getSubExpr(), Pred, S1);
+
+ for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
+ NodeTy* N1 = *I1;
+ StateTy St = N1->getState();
+
+ switch (U->getOpcode()) {
+ case UnaryOperator::PostInc: {
+ const LValue& L1 = GetLValue(St, U->getSubExpr());
+ RValue R1 = cast<RValue>(GetValue(St, L1));
+
+ QualType T = U->getType();
+ llvm::APInt One(getContext()->getTypeSize(T,U->getLocStart()), 1);
+ RValue R2 = RValue::GetRValue(ValMgr, One);
+
+ RValue Result = R1.EvalAdd(ValMgr, R2);
+ Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
+ break;
+ }
+
+ case UnaryOperator::PostDec: {
+ const LValue& L1 = GetLValue(St, U->getSubExpr());
+ RValue R1 = cast<RValue>(GetValue(St, L1));
+
+ QualType T = U->getType();
+ llvm::APInt One(getContext()->getTypeSize(T,U->getLocStart()), 1);
+ RValue R2 = RValue::GetRValue(ValMgr, One);
+
+ RValue Result = R1.EvalSub(ValMgr, R2);
+ Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
+ break;
+ }
+
+ case UnaryOperator::PreInc: {
+ const LValue& L1 = GetLValue(St, U->getSubExpr());
+ RValue R1 = cast<RValue>(GetValue(St, L1));
+
+ QualType T = U->getType();
+ llvm::APInt One(getContext()->getTypeSize(T,U->getLocStart()), 1);
+ RValue R2 = RValue::GetRValue(ValMgr, One);
+
+ RValue Result = R1.EvalAdd(ValMgr, R2);
+ Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
+ break;
+ }
+
+ case UnaryOperator::PreDec: {
+ const LValue& L1 = GetLValue(St, U->getSubExpr());
+ RValue R1 = cast<RValue>(GetValue(St, L1));
+
+ QualType T = U->getType();
+ llvm::APInt One(getContext()->getTypeSize(T,U->getLocStart()), 1);
+ RValue R2 = RValue::GetRValue(ValMgr, One);
+
+ RValue Result = R1.EvalSub(ValMgr, R2);
+ Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
+ break;
+ }
+
+ default: ;
+ assert (false && "Not implemented.");
+ }
+ }
+}
+
void GRConstants::VisitBinaryOperator(BinaryOperator* B,
GRConstants::NodeTy* Pred,
GRConstants::NodeSet& Dst) {
@@ -848,6 +921,10 @@
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
break;
+ case Stmt::UnaryOperatorClass:
+ VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
+ break;
+
case Stmt::ParenExprClass:
Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
break;