diff --git a/Changelog.md b/Changelog.md index c118e9f248a4..16e42aff26d9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Bugfixes: * SMTChecker: Fix internal error when using an empty tuple in a conditional operator. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. * Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence. + * StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals. * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 10c2c922ca47..563295e23c00 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -298,7 +298,8 @@ bool StaticAnalyzer::visit(BinaryOperation const& _operation) { if ( *_operation.rightExpression().annotation().isPure && - (_operation.getOperator() == Token::Div || _operation.getOperator() == Token::Mod) + (_operation.getOperator() == Token::Div || _operation.getOperator() == Token::Mod) && + ConstantEvaluator::evaluate(m_errorReporter, _operation.leftExpression()) ) if (auto rhs = ConstantEvaluator::evaluate(m_errorReporter, _operation.rightExpression())) if (rhs->value == 0) diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol new file mode 100644 index 000000000000..c3a51cc29760 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a; + constructor() { a /= (((2)*2)%4); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol new file mode 100644 index 000000000000..9404f0ce9711 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a = 5; + constructor() { a /= uint(0); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol new file mode 100644 index 000000000000..66540568f357 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol @@ -0,0 +1,4 @@ +contract A { + constructor() { uint a; a / 0; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol new file mode 100644 index 000000000000..1e9f1e1fa731 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a = 5; + constructor() { a %= uint(((2)*2)%4); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol new file mode 100644 index 000000000000..2fb6e1df09af --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a; + constructor() { a = 5; a %= 0; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol new file mode 100644 index 000000000000..0722a096fc85 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol @@ -0,0 +1,4 @@ +contract A { + constructor() { uint a; a % 0; } +} +// ----