@@ -569,11 +569,18 @@ void BMC::endVisit(UnaryOperation const& _op)
569
569
return ;
570
570
571
571
if (_op.getOperator () == Token::Sub && smt::isInteger (*_op.annotation ().type ))
572
+ {
573
+ addVerificationTarget (
574
+ VerificationTargetType::Underflow,
575
+ expr (_op),
576
+ &_op
577
+ );
572
578
addVerificationTarget (
573
- VerificationTargetType::UnderOverflow ,
579
+ VerificationTargetType::Overflow ,
574
580
expr (_op),
575
581
&_op
576
582
);
583
+ }
577
584
}
578
585
579
586
void BMC::endVisit (BinaryOperation const & _op)
@@ -813,32 +820,29 @@ std::pair<smtutil::Expression, smtutil::Expression> BMC::arithmeticOperation(
813
820
if (_op == Token::Mod)
814
821
return values;
815
822
816
- VerificationTargetType type;
817
823
// The order matters here:
818
824
// If _op is Div and intType is signed, we only care about overflow.
819
825
if (_op == Token::Div)
820
826
{
821
827
if (intType->isSigned ())
822
828
// Signed division can only overflow.
823
- type = VerificationTargetType::Overflow;
829
+ addVerificationTarget ( VerificationTargetType::Overflow, values. second , &_expression) ;
824
830
else
825
831
// Unsigned division cannot underflow/overflow.
826
832
return values;
827
833
}
828
834
else if (intType->isSigned ())
829
- type = VerificationTargetType::UnderOverflow;
835
+ {
836
+ addVerificationTarget (VerificationTargetType::Overflow, values.second , &_expression);
837
+ addVerificationTarget (VerificationTargetType::Underflow, values.second , &_expression);
838
+ }
830
839
else if (_op == Token::Sub)
831
- type = VerificationTargetType::Underflow;
840
+ addVerificationTarget ( VerificationTargetType::Underflow, values. second , &_expression) ;
832
841
else if (_op == Token::Add || _op == Token::Mul)
833
- type = VerificationTargetType::Overflow;
842
+ addVerificationTarget ( VerificationTargetType::Overflow, values. second , &_expression) ;
834
843
else
835
844
solAssert (false , " " );
836
845
837
- addVerificationTarget (
838
- type,
839
- values.second ,
840
- &_expression
841
- );
842
846
return values;
843
847
}
844
848
@@ -919,6 +923,12 @@ void BMC::checkVerificationTargets()
919
923
920
924
void BMC::checkVerificationTarget (BMCVerificationTarget& _target)
921
925
{
926
+ if (
927
+ m_solvedTargets.count (_target.expression ) &&
928
+ m_solvedTargets.at (_target.expression ).count (_target.type )
929
+ )
930
+ return ;
931
+
922
932
switch (_target.type )
923
933
{
924
934
case VerificationTargetType::ConstantCondition:
@@ -930,10 +940,6 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target)
930
940
case VerificationTargetType::Overflow:
931
941
checkOverflow (_target);
932
942
break ;
933
- case VerificationTargetType::UnderOverflow:
934
- checkUnderflow (_target);
935
- checkOverflow (_target);
936
- break ;
937
943
case VerificationTargetType::DivByZero:
938
944
checkDivByZero (_target);
939
945
break ;
@@ -961,19 +967,10 @@ void BMC::checkConstantCondition(BMCVerificationTarget& _target)
961
967
void BMC::checkUnderflow (BMCVerificationTarget& _target)
962
968
{
963
969
solAssert (
964
- _target.type == VerificationTargetType::Underflow ||
965
- _target.type == VerificationTargetType::UnderOverflow,
970
+ _target.type == VerificationTargetType::Underflow,
966
971
" "
967
972
);
968
973
969
- if (
970
- m_solvedTargets.count (_target.expression ) && (
971
- m_solvedTargets.at (_target.expression ).count (VerificationTargetType::Underflow) ||
972
- m_solvedTargets.at (_target.expression ).count (VerificationTargetType::UnderOverflow)
973
- )
974
- )
975
- return ;
976
-
977
974
auto const * intType = dynamic_cast <IntegerType const *>(_target.expression ->annotation ().type );
978
975
if (!intType)
979
976
intType = TypeProvider::uint256 ();
@@ -994,19 +991,10 @@ void BMC::checkUnderflow(BMCVerificationTarget& _target)
994
991
void BMC::checkOverflow (BMCVerificationTarget& _target)
995
992
{
996
993
solAssert (
997
- _target.type == VerificationTargetType::Overflow ||
998
- _target.type == VerificationTargetType::UnderOverflow,
994
+ _target.type == VerificationTargetType::Overflow,
999
995
" "
1000
996
);
1001
997
1002
- if (
1003
- m_solvedTargets.count (_target.expression ) && (
1004
- m_solvedTargets.at (_target.expression ).count (VerificationTargetType::Overflow) ||
1005
- m_solvedTargets.at (_target.expression ).count (VerificationTargetType::UnderOverflow)
1006
- )
1007
- )
1008
- return ;
1009
-
1010
998
auto const * intType = dynamic_cast <IntegerType const *>(_target.expression ->annotation ().type );
1011
999
if (!intType)
1012
1000
intType = TypeProvider::uint256 ();
@@ -1028,12 +1016,6 @@ void BMC::checkDivByZero(BMCVerificationTarget& _target)
1028
1016
{
1029
1017
solAssert (_target.type == VerificationTargetType::DivByZero, " " );
1030
1018
1031
- if (
1032
- m_solvedTargets.count (_target.expression ) &&
1033
- m_solvedTargets.at (_target.expression ).count (VerificationTargetType::DivByZero)
1034
- )
1035
- return ;
1036
-
1037
1019
checkCondition (
1038
1020
_target,
1039
1021
_target.constraints && (_target.value == 0 ),
@@ -1051,11 +1033,6 @@ void BMC::checkBalance(BMCVerificationTarget& _target)
1051
1033
{
1052
1034
solAssert (_target.type == VerificationTargetType::Balance, " " );
1053
1035
1054
- if (
1055
- m_solvedTargets.count (_target.expression ) &&
1056
- m_solvedTargets.at (_target.expression ).count (VerificationTargetType::Balance)
1057
- )
1058
- return ;
1059
1036
checkCondition (
1060
1037
_target,
1061
1038
_target.constraints && _target.value ,
@@ -1072,12 +1049,6 @@ void BMC::checkAssert(BMCVerificationTarget& _target)
1072
1049
{
1073
1050
solAssert (_target.type == VerificationTargetType::Assert, " " );
1074
1051
1075
- if (
1076
- m_solvedTargets.count (_target.expression ) &&
1077
- m_solvedTargets.at (_target.expression ).count (_target.type )
1078
- )
1079
- return ;
1080
-
1081
1052
checkCondition (
1082
1053
_target,
1083
1054
_target.constraints && !_target.value ,
0 commit comments