Merge pull request #3107 from ethereum/constexpr-detailed

More detailed errors for invalid array lengths (such as division by zero)
This commit is contained in:
Alex Beregszaszi 2017-10-20 13:23:16 +01:00 committed by GitHub
commit bdd2858bfd
3 changed files with 27 additions and 3 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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)