aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)