Throw on division by zero.

This commit is contained in:
chriseth 2016-08-12 16:50:37 +02:00
parent e4578982c6
commit e7084d9e16
3 changed files with 33 additions and 3 deletions

View File

@ -57,6 +57,8 @@ Operators:
Division always truncates (it just maps to the DIV opcode of the EVM), but it does not truncate if both
operators are :ref:`literals<rational_literals>` (or literal expressions).
Division by zero and modulus with zero throws an exception.
.. index:: address, balance, send, call, callcode, delegatecall
.. _address:

View File

@ -1324,11 +1324,18 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
m_context << Instruction::MUL;
break;
case Token::Div:
m_context << (c_isSigned ? Instruction::SDIV : Instruction::DIV);
break;
case Token::Mod:
m_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD);
{
// Test for division by zero
m_context << Instruction::DUP2 << Instruction::ISZERO;
m_context.appendConditionalJumpTo(m_context.errorTag());
if (_operator == Token::Div)
m_context << (c_isSigned ? Instruction::SDIV : Instruction::DIV);
else
m_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD);
break;
}
case Token::Exp:
m_context << Instruction::EXP;
break;

View File

@ -6208,6 +6208,27 @@ BOOST_AUTO_TEST_CASE(addmod_mulmod)
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(0)));
}
BOOST_AUTO_TEST_CASE(divisiod_by_zero)
{
char const* sourceCode = R"(
contract C {
function div(uint a, uint b) returns (uint) {
return a / b;
}
function mod(uint a, uint b) returns (uint) {
return a % b;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("div(uint256,uint256)", 7, 2) == encodeArgs(u256(3)));
// throws
BOOST_CHECK(callContractFunction("div(uint256,uint256)", 7, 0) == encodeArgs());
BOOST_CHECK(callContractFunction("mod(uint256,uint256)", 7, 2) == encodeArgs(u256(1)));
// throws
BOOST_CHECK(callContractFunction("mod(uint256,uint256)", 7, 0) == encodeArgs());
}
BOOST_AUTO_TEST_CASE(string_allocation_bug)
{
char const* sourceCode = R"(