Skip to content

Commit 3c5aa3b

Browse files
committed
Remove UnderOverflow verification target for BMC engine
1 parent 7c94f53 commit 3c5aa3b

File tree

4 files changed

+26
-55
lines changed

4 files changed

+26
-55
lines changed

Changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Language Features:
55

66

77
Compiler Features:
8-
* SMTChecker: Create balance check verification target for CHC engine.
8+
* SMTChecker: Add balance check verification target for CHC engine.
99

1010
Bugfixes:
1111
* Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence.

libsolidity/formal/BMC.cpp

Lines changed: 23 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,18 @@ void BMC::endVisit(UnaryOperation const& _op)
569569
return;
570570

571571
if (_op.getOperator() == Token::Sub && smt::isInteger(*_op.annotation().type))
572+
{
573+
addVerificationTarget(
574+
VerificationTargetType::Underflow,
575+
expr(_op),
576+
&_op
577+
);
572578
addVerificationTarget(
573-
VerificationTargetType::UnderOverflow,
579+
VerificationTargetType::Overflow,
574580
expr(_op),
575581
&_op
576582
);
583+
}
577584
}
578585

579586
void BMC::endVisit(BinaryOperation const& _op)
@@ -813,32 +820,29 @@ std::pair<smtutil::Expression, smtutil::Expression> BMC::arithmeticOperation(
813820
if (_op == Token::Mod)
814821
return values;
815822

816-
VerificationTargetType type;
817823
// The order matters here:
818824
// If _op is Div and intType is signed, we only care about overflow.
819825
if (_op == Token::Div)
820826
{
821827
if (intType->isSigned())
822828
// Signed division can only overflow.
823-
type = VerificationTargetType::Overflow;
829+
addVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression);
824830
else
825831
// Unsigned division cannot underflow/overflow.
826832
return values;
827833
}
828834
else if (intType->isSigned())
829-
type = VerificationTargetType::UnderOverflow;
835+
{
836+
addVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression);
837+
addVerificationTarget(VerificationTargetType::Underflow, values.second, &_expression);
838+
}
830839
else if (_op == Token::Sub)
831-
type = VerificationTargetType::Underflow;
840+
addVerificationTarget(VerificationTargetType::Underflow, values.second, &_expression);
832841
else if (_op == Token::Add || _op == Token::Mul)
833-
type = VerificationTargetType::Overflow;
842+
addVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression);
834843
else
835844
solAssert(false, "");
836845

837-
addVerificationTarget(
838-
type,
839-
values.second,
840-
&_expression
841-
);
842846
return values;
843847
}
844848

@@ -919,6 +923,12 @@ void BMC::checkVerificationTargets()
919923

920924
void BMC::checkVerificationTarget(BMCVerificationTarget& _target)
921925
{
926+
if (
927+
m_solvedTargets.count(_target.expression) &&
928+
m_solvedTargets.at(_target.expression).count(_target.type)
929+
)
930+
return;
931+
922932
switch (_target.type)
923933
{
924934
case VerificationTargetType::ConstantCondition:
@@ -930,10 +940,6 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target)
930940
case VerificationTargetType::Overflow:
931941
checkOverflow(_target);
932942
break;
933-
case VerificationTargetType::UnderOverflow:
934-
checkUnderflow(_target);
935-
checkOverflow(_target);
936-
break;
937943
case VerificationTargetType::DivByZero:
938944
checkDivByZero(_target);
939945
break;
@@ -961,19 +967,10 @@ void BMC::checkConstantCondition(BMCVerificationTarget& _target)
961967
void BMC::checkUnderflow(BMCVerificationTarget& _target)
962968
{
963969
solAssert(
964-
_target.type == VerificationTargetType::Underflow ||
965-
_target.type == VerificationTargetType::UnderOverflow,
970+
_target.type == VerificationTargetType::Underflow,
966971
""
967972
);
968973

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-
977974
auto const* intType = dynamic_cast<IntegerType const*>(_target.expression->annotation().type);
978975
if (!intType)
979976
intType = TypeProvider::uint256();
@@ -994,19 +991,10 @@ void BMC::checkUnderflow(BMCVerificationTarget& _target)
994991
void BMC::checkOverflow(BMCVerificationTarget& _target)
995992
{
996993
solAssert(
997-
_target.type == VerificationTargetType::Overflow ||
998-
_target.type == VerificationTargetType::UnderOverflow,
994+
_target.type == VerificationTargetType::Overflow,
999995
""
1000996
);
1001997

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-
1010998
auto const* intType = dynamic_cast<IntegerType const*>(_target.expression->annotation().type);
1011999
if (!intType)
10121000
intType = TypeProvider::uint256();
@@ -1028,12 +1016,6 @@ void BMC::checkDivByZero(BMCVerificationTarget& _target)
10281016
{
10291017
solAssert(_target.type == VerificationTargetType::DivByZero, "");
10301018

1031-
if (
1032-
m_solvedTargets.count(_target.expression) &&
1033-
m_solvedTargets.at(_target.expression).count(VerificationTargetType::DivByZero)
1034-
)
1035-
return;
1036-
10371019
checkCondition(
10381020
_target,
10391021
_target.constraints && (_target.value == 0),
@@ -1051,11 +1033,6 @@ void BMC::checkBalance(BMCVerificationTarget& _target)
10511033
{
10521034
solAssert(_target.type == VerificationTargetType::Balance, "");
10531035

1054-
if (
1055-
m_solvedTargets.count(_target.expression) &&
1056-
m_solvedTargets.at(_target.expression).count(VerificationTargetType::Balance)
1057-
)
1058-
return;
10591036
checkCondition(
10601037
_target,
10611038
_target.constraints && _target.value,
@@ -1072,12 +1049,6 @@ void BMC::checkAssert(BMCVerificationTarget& _target)
10721049
{
10731050
solAssert(_target.type == VerificationTargetType::Assert, "");
10741051

1075-
if (
1076-
m_solvedTargets.count(_target.expression) &&
1077-
m_solvedTargets.at(_target.expression).count(_target.type)
1078-
)
1079-
return;
1080-
10811052
checkCondition(
10821053
_target,
10831054
_target.constraints && !_target.value,

libsolidity/formal/ModelCheckerSettings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ struct ModelCheckerInvariants
113113
std::set<InvariantType> invariants;
114114
};
115115

116-
enum class VerificationTargetType { ConstantCondition, Underflow, Overflow, UnderOverflow, DivByZero, Balance, Assert, PopEmptyArray, OutOfBounds };
116+
enum class VerificationTargetType { ConstantCondition, Underflow, Overflow, DivByZero, Balance, Assert, PopEmptyArray, OutOfBounds };
117117

118118
struct ModelCheckerTargets
119119
{

test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ contract C {
1212
// SMTIgnoreCex: yes
1313
// ----
1414
// Warning 6328: (166-201): CHC: Assertion violation happens here.
15-
// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them.
15+
// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them.

0 commit comments

Comments
 (0)