aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-10-04 17:59:21 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2017-10-20 18:59:18 +0800
commit3a8324266f470b18763054ed5caa791e8e8410a7 (patch)
tree1246f7a431a8e380d0348ba239e0a412fd69182f
parent4e7d1440ab84ba0566c7c75ff61b2f9e70738ef4 (diff)
downloaddexon-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.md1
-rw-r--r--libsolidity/analysis/ConstantEvaluator.cpp23
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp6
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)