From: Ted Kremenek Date: Fri, 15 Feb 2008 23:15:23 +0000 (+0000) Subject: Refactored code for transfer functions for binary operators involving two LValues. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6fbdcdb3b84d8a6bffa59b0848a8f53cf0bd11a;p=clang Refactored code for transfer functions for binary operators involving two LValues. Fixed bug in transfer functions for sizeof(*); we were incorrectly evaluating to a value of the wrong type. Fixed bug in transfer functions for compound assignments where we did not properly handle assignments involving dereferences of symbolic values. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47190 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp index 33f7f51504..4bcdd5fb70 100644 --- a/Analysis/GRExprEngine.cpp +++ b/Analysis/GRExprEngine.cpp @@ -473,7 +473,7 @@ void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* S, Nodify(Dst, S, Pred, SetValue(Pred->getState(), S, - NonLValue::GetValue(ValMgr, size, getContext().IntTy, L))); + NonLValue::GetValue(ValMgr, size, S->getType(), L))); } @@ -573,7 +573,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, Nodify(Dst, U, N1, SetValue(St, U, NonLValue::GetValue(ValMgr, size, - getContext().IntTy, L))); + U->getType(), L))); break; } @@ -730,15 +730,20 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, Result = EvalBinaryOp(ValMgr, Op, L1, L2); } else { + QualType T1 = B->getLHS()->getType(); + QualType T2 = B->getRHS()->getType(); + // An operation between two variables of a non-lvalue type. Result = EvalBinaryOp(ValMgr, Op, - cast(GetValue(N1->getState(), L1)), - cast(GetValue(N2->getState(), L2))); + cast(GetValue(N1->getState(), L1, &T1)), + cast(GetValue(N2->getState(), L2, &T2))); } } else { // Any other operation between two Non-LValues. - const NonLValue& R1 = cast(GetValue(N1->getState(), L1)); + QualType T = B->getLHS()->getType(); + const NonLValue& R1 = cast(GetValue(N1->getState(), + L1, &T)); const NonLValue& R2 = cast(V2); Result = EvalBinaryOp(ValMgr, Op, R1, R2); } diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp index c9827d9d10..75dc256d79 100644 --- a/Analysis/GRSimpleVals.cpp +++ b/Analysis/GRSimpleVals.cpp @@ -163,6 +163,24 @@ NonLValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr, } +// Binary Operators (except assignments and comma). + +RValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr, + BinaryOperator::Opcode Op, + LValue LHS, LValue RHS) { + + switch (Op) { + default: + return UnknownVal(); + + case BinaryOperator::EQ: + return EvalEQ(ValMgr, LHS, RHS); + + case BinaryOperator::NE: + return EvalNE(ValMgr, LHS, RHS); + } +} + // Pointer arithmetic. LValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr, diff --git a/Analysis/GRSimpleVals.h b/Analysis/GRSimpleVals.h index b00dd3ca39..34b1d4f183 100644 --- a/Analysis/GRSimpleVals.h +++ b/Analysis/GRSimpleVals.h @@ -44,14 +44,19 @@ public: BinaryOperator::Opcode Op, NonLValue LHS, NonLValue RHS); + virtual RValue EvalBinaryOp(ValueManager& ValMgr, + BinaryOperator::Opcode Op, + LValue LHS, LValue RHS); + // Pointer arithmetic. virtual LValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op, LValue LHS, NonLValue RHS); +protected: // Equality operators for LValues. - virtual NonLValue EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS); - virtual NonLValue EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS); + NonLValue EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS); + NonLValue EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS); }; diff --git a/Analysis/GRTransferFuncs.cpp b/Analysis/GRTransferFuncs.cpp index 33663d6c60..3716ed9691 100644 --- a/Analysis/GRTransferFuncs.cpp +++ b/Analysis/GRTransferFuncs.cpp @@ -39,21 +39,3 @@ RValue GRTransferFuncs::EvalCast(ValueManager& ValMgr, RValue X, return X; } - -// Binary Operators (except assignments and comma). - -RValue GRTransferFuncs::EvalBinaryOp(ValueManager& ValMgr, - BinaryOperator::Opcode Op, - LValue LHS, LValue RHS) { - - switch (Op) { - default: - assert (false && "Not yet implemented."); - - case BinaryOperator::EQ: - return EvalEQ(ValMgr, LHS, RHS); - - case BinaryOperator::NE: - return EvalNE(ValMgr, LHS, RHS); - } -} \ No newline at end of file diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index 19e87dcd94..53491d532e 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -43,9 +43,9 @@ public: BinaryOperator::Opcode Op, NonLValue LHS, NonLValue RHS) = 0; - RValue EvalBinaryOp(ValueManager& ValMgr, - BinaryOperator::Opcode Op, - LValue LHS, LValue RHS); + virtual RValue EvalBinaryOp(ValueManager& ValMgr, + BinaryOperator::Opcode Op, + LValue LHS, LValue RHS) = 0; // Pointer arithmetic. @@ -64,11 +64,6 @@ public: else return EvalBinaryOp(ValMgr, Op, cast(L), cast(R)); } - - - // Equality operators for LValues. - virtual NonLValue EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS) = 0; - virtual NonLValue EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS) = 0; }; } // end clang namespace