From: Ted Kremenek Date: Thu, 24 Jan 2008 02:28:56 +0000 (+0000) Subject: Added transfer functions for pre- and post- increment/decrement operators. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b8009a3e3a1479203d315b74712552a4ce3e200;p=clang 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 0a9c68a7fe..0c827baec7 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -213,7 +213,7 @@ public: 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 support. static inline bool classof(const ExprValue* V) { @@ -359,9 +359,8 @@ RValueMayEqualSet::EvalMul(ValueManager& ValMgr, 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 @@ protected: bool StateCleaned; + ASTContext* getContext() const { return ValMgr.getContext(); } + public: GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL), StmtEntryNode(NULL), CurrentStmt(NULL) {} @@ -558,6 +559,9 @@ public: /// 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 @@ ExprValue GRConstants::GetValue(const StateTy& St, Stmt* S) { return GetValue(St, LValueDecl(cast(S)->getDecl())); case Stmt::IntegerLiteralClass: - return RValue::GetRValue(ValMgr, cast(S)); + return RValue::GetRValue(ValMgr, cast(S)->getValue()); case Stmt::ImplicitCastExprClass: { ImplicitCastExpr* C = cast(S); @@ -742,6 +746,75 @@ void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred, } } +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(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(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(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(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 @@ void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred, VisitBinaryOperator(cast(S), Pred, Dst); break; + case Stmt::UnaryOperatorClass: + VisitUnaryOperator(cast(S), Pred, Dst); + break; + case Stmt::ParenExprClass: Visit(cast(S)->getSubExpr(), Pred, Dst); break;