diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-06 22:50:25 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-06 22:50:25 +0000 |
commit | cf78b6a771bb4537d5ee8fa44e718e842c2f70c7 (patch) | |
tree | 5b29b3c10d3fc686738c29a676687c8e8717d240 /Analysis/GRConstants.cpp | |
parent | 510190777c4bd53e960eea4665b204778fec1b64 (diff) |
Major code refactoring/cleanup with transfer function logic. Now the
code structure is more suitable for additional symbolic analysis.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46831 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/GRConstants.cpp')
-rw-r--r-- | Analysis/GRConstants.cpp | 163 |
1 files changed, 60 insertions, 103 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 2b44bf7df6..516af280f4 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -537,7 +537,7 @@ void GRConstants::VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst) { NodeTy* N = *I1; StateTy St = N->getState(); const RValue& V = GetValue(St, E); - Nodify(Dst, CastE, N, SetValue(St, CastE, V.Cast(ValMgr, CastE))); + Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE))); } } @@ -585,7 +585,10 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, case UnaryOperator::PostInc: { const LValue& L1 = GetLValue(St, U->getSubExpr()); NonLValue R1 = cast<NonLValue>(GetValue(St, L1)); - NonLValue Result = R1.Add(ValMgr, GetRValueConstant(1U, U)); + + NonLValue Result = R1.EvalBinaryOp(ValMgr, BinaryOperator::Add, + GetRValueConstant(1U, U)); + Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result)); break; } @@ -593,7 +596,10 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, case UnaryOperator::PostDec: { const LValue& L1 = GetLValue(St, U->getSubExpr()); NonLValue R1 = cast<NonLValue>(GetValue(St, L1)); - NonLValue Result = R1.Sub(ValMgr, GetRValueConstant(1U, U)); + + NonLValue Result = R1.EvalBinaryOp(ValMgr, BinaryOperator::Sub, + GetRValueConstant(1U, U)); + Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result)); break; } @@ -601,7 +607,10 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, case UnaryOperator::PreInc: { const LValue& L1 = GetLValue(St, U->getSubExpr()); NonLValue R1 = cast<NonLValue>(GetValue(St, L1)); - NonLValue Result = R1.Add(ValMgr, GetRValueConstant(1U, U)); + + NonLValue Result = R1.EvalBinaryOp(ValMgr, BinaryOperator::Add, + GetRValueConstant(1U, U)); + Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result)); break; } @@ -609,20 +618,23 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, case UnaryOperator::PreDec: { const LValue& L1 = GetLValue(St, U->getSubExpr()); NonLValue R1 = cast<NonLValue>(GetValue(St, L1)); - NonLValue Result = R1.Sub(ValMgr, GetRValueConstant(1U, U)); + + NonLValue Result = R1.EvalBinaryOp(ValMgr, BinaryOperator::Sub, + GetRValueConstant(1U, U)); + Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result)); break; } case UnaryOperator::Minus: { const NonLValue& R1 = cast<NonLValue>(GetValue(St, U->getSubExpr())); - Nodify(Dst, U, N1, SetValue(St, U, R1.UnaryMinus(ValMgr, U))); + Nodify(Dst, U, N1, SetValue(St, U, R1.EvalMinus(ValMgr, U))); break; } case UnaryOperator::Not: { const NonLValue& R1 = cast<NonLValue>(GetValue(St, U->getSubExpr())); - Nodify(Dst, U, N1, SetValue(St, U, R1.BitwiseComplement(ValMgr))); + Nodify(Dst, U, N1, SetValue(St, U, R1.EvalComplement(ValMgr))); break; } @@ -635,14 +647,18 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, RValue V1 = GetValue(St, U->getSubExpr()); if (isa<LValue>(V1)) { - lval::ConcreteInt V2(ValMgr.getValue(0, U->getSubExpr()->getType())); - Nodify(Dst, U, N1, SetValue(St, U, - cast<LValue>(V1).EQ(ValMgr, V2))); + const LValue& L1 = cast<LValue>(V1); + lval::ConcreteInt V2(ValMgr.getZeroWithPtrWidth()); + Nodify(Dst, U, N1, + SetValue(St, U, L1.EvalBinaryOp(ValMgr, BinaryOperator::EQ, + V2))); } else { + const NonLValue& R1 = cast<NonLValue>(V1); nonlval::ConcreteInt V2(ValMgr.getZeroWithPtrWidth()); - Nodify(Dst, U, N1, SetValue(St, U, - cast<NonLValue>(V1).EQ(ValMgr, V2))); + Nodify(Dst, U, N1, + SetValue(St, U, R1.EvalBinaryOp(ValMgr, BinaryOperator::EQ, + V2))); } break; @@ -687,122 +703,63 @@ void GRConstants::VisitBinaryOperator(BinaryOperator* B, Visit(B->getRHS(), N1, S2); for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) { + NodeTy* N2 = *I2; StateTy St = N2->getState(); const RValue& V2 = GetValue(St, B->getRHS()); - switch (B->getOpcode()) { - default: - Dst.Add(N2); - break; - - // Arithmetic operators. - - case BinaryOperator::Add: { - const NonLValue& R1 = cast<NonLValue>(V1); - const NonLValue& R2 = cast<NonLValue>(V2); - - Nodify(Dst, B, N2, SetValue(St, B, R1.Add(ValMgr, R2))); - break; - } - - case BinaryOperator::Sub: { - const NonLValue& R1 = cast<NonLValue>(V1); - const NonLValue& R2 = cast<NonLValue>(V2); - Nodify(Dst, B, N2, SetValue(St, B, R1.Sub(ValMgr, R2))); - break; - } - - case BinaryOperator::Mul: { - const NonLValue& R1 = cast<NonLValue>(V1); - const NonLValue& R2 = cast<NonLValue>(V2); - Nodify(Dst, B, N2, SetValue(St, B, R1.Mul(ValMgr, R2))); - break; - } + BinaryOperator::Opcode Op = B->getOpcode(); + + if (Op <= BinaryOperator::Or) { + + if (isa<LValue>(V1)) { + // FIXME: Add support for RHS being a non-lvalue. + const LValue& L1 = cast<LValue>(V1); + const LValue& L2 = cast<LValue>(V2); - case BinaryOperator::Div: { - const NonLValue& R1 = cast<NonLValue>(V1); - const NonLValue& R2 = cast<NonLValue>(V2); - Nodify(Dst, B, N2, SetValue(St, B, R1.Div(ValMgr, R2))); - break; + Nodify(Dst, B, N2, SetValue(St, B, L1.EvalBinaryOp(ValMgr, Op, L2))); } - - case BinaryOperator::Rem: { + else { const NonLValue& R1 = cast<NonLValue>(V1); const NonLValue& R2 = cast<NonLValue>(V2); - Nodify(Dst, B, N2, SetValue(St, B, R1.Rem(ValMgr, R2))); - break; + + Nodify(Dst, B, N2, SetValue(St, B, R1.EvalBinaryOp(ValMgr, Op, R2))); } - - // Assignment operators. - + + continue; + } + + switch (Op) { case BinaryOperator::Assign: { const LValue& L1 = cast<LValue>(V1); Nodify(Dst, B, N2, SetValue(SetValue(St, B, V2), L1, V2)); break; } + + default: { // Compound assignment operators. - case BinaryOperator::AddAssign: { - const LValue& L1 = cast<LValue>(V1); - NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1)); - NonLValue Result = R1.Add(ValMgr, cast<NonLValue>(V2)); - Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result)); - break; - } - - case BinaryOperator::SubAssign: { - const LValue& L1 = cast<LValue>(V1); - NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1)); - NonLValue Result = R1.Sub(ValMgr, cast<NonLValue>(V2)); - Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result)); - break; - } - - case BinaryOperator::MulAssign: { - const LValue& L1 = cast<LValue>(V1); - NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1)); - NonLValue Result = R1.Mul(ValMgr, cast<NonLValue>(V2)); - Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result)); - break; - } - - case BinaryOperator::DivAssign: { - const LValue& L1 = cast<LValue>(V1); - NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1)); - NonLValue Result = R1.Div(ValMgr, cast<NonLValue>(V2)); - Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result)); - break; - } - - case BinaryOperator::RemAssign: { + assert (B->isCompoundAssignmentOp()); + const LValue& L1 = cast<LValue>(V1); - NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1)); - NonLValue Result = R1.Rem(ValMgr, cast<NonLValue>(V2)); - Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result)); - break; - } + RValue Result = cast<NonLValue>(InvalidValue()); - // Equality operators. - - case BinaryOperator::EQ: - // FIXME: should we allow XX.EQ() to return a set of values, - // allowing state bifurcation? In such cases, they will also - // modify the state (meaning that a new state will be returned - // as well). - assert (B->getType() == getContext().IntTy); + Op = (BinaryOperator::Opcode) + (((unsigned) Op) - ((unsigned) BinaryOperator::MulAssign)); - if (isa<LValue>(V1)) { - const LValue& L1 = cast<LValue>(V1); + if (isa<LValue>(V2)) { + // FIXME: Add support for Non-LValues on RHS. const LValue& L2 = cast<LValue>(V2); - Nodify(Dst, B, N2, SetValue(St, B, L1.EQ(ValMgr, L2))); + Result = L1.EvalBinaryOp(ValMgr, Op, L2); } else { - const NonLValue& R1 = cast<NonLValue>(V1); + const NonLValue& R1 = cast<NonLValue>(GetValue(N1->getState(), L1)); const NonLValue& R2 = cast<NonLValue>(V2); - Nodify(Dst, B, N2, SetValue(St, B, R1.EQ(ValMgr, R2))); + Result = R1.EvalBinaryOp(ValMgr, Op, R2); } + Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result)); break; + } } } } |