diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2017-10-04 17:59:21 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2017-10-20 18:59:18 +0800 |
commit | 3a8324266f470b18763054ed5caa791e8e8410a7 (patch) | |
tree | 1246f7a431a8e380d0348ba239e0a412fd69182f | |
parent | 4e7d1440ab84ba0566c7c75ff61b2f9e70738ef4 (diff) | |
download | dexon-solidity-3a8324266f470b18763054ed5caa791e8e8410a7.tar.gz dexon-solidity-3a8324266f470b18763054ed5caa791e8e8410a7.tar.zst dexon-solidity-3a8324266f470b18763054ed5caa791e8e8410a7.zip |
More detailed errors for invalid array lengths (such as division by zero).
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | libsolidity/analysis/ConstantEvaluator.cpp | 23 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 6 |
3 files changed, 27 insertions, 3 deletions
diff --git a/Changelog.md b/Changelog.md index 68b9973f..e691711b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Features: * Syntax Checker: Turn the usage of ``callcode`` into an error as experimental 0.5.0 feature. + * Type Checker: More detailed errors for invalid array lengths (such as division by zero). Bugfixes: diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 6636ad97..bc3b7cf1 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -28,6 +28,7 @@ using namespace std; using namespace dev; using namespace dev::solidity; +/// FIXME: this is pretty much a copy of TypeChecker::endVisit(BinaryOperation) void ConstantEvaluator::endVisit(UnaryOperation const& _operation) { TypePointer const& subType = _operation.subExpression().annotation().type; @@ -37,6 +38,7 @@ void ConstantEvaluator::endVisit(UnaryOperation const& _operation) _operation.annotation().type = t; } +/// FIXME: this is pretty much a copy of TypeChecker::endVisit(BinaryOperation) void ConstantEvaluator::endVisit(BinaryOperation const& _operation) { TypePointer const& leftType = _operation.leftExpression().annotation().type; @@ -46,9 +48,24 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation) if (!dynamic_cast<RationalNumberType const*>(rightType.get())) m_errorReporter.fatalTypeError(_operation.rightExpression().location(), "Invalid constant expression."); TypePointer commonType = leftType->binaryOperatorResult(_operation.getOperator(), rightType); - if (Token::isCompareOp(_operation.getOperator())) - commonType = make_shared<BoolType>(); - _operation.annotation().type = commonType; + if (!commonType) + { + m_errorReporter.typeError( + _operation.location(), + "Operator " + + string(Token::toString(_operation.getOperator())) + + " not compatible with types " + + leftType->toString() + + " and " + + rightType->toString() + ); + commonType = leftType; + } + _operation.annotation().commonType = commonType; + _operation.annotation().type = + Token::isCompareOp(_operation.getOperator()) ? + make_shared<BoolType>() : + commonType; } void ConstantEvaluator::endVisit(Literal const& _literal) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 9b5ea349..e5990e9b 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -7247,6 +7247,12 @@ BOOST_AUTO_TEST_CASE(array_length_invalid_expression) } )"; CHECK_ERROR(text, TypeError, "Invalid literal value."); + text = R"( + contract C { + uint[3/0] ids; + } + )"; + CHECK_ERROR(text, TypeError, "Operator / not compatible with types int_const 3 and int_const 0"); } BOOST_AUTO_TEST_CASE(no_address_members_on_contract) |