From c28ed2a6191fd16c4be92a9adb53d5ff3215a34d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 5 Oct 2017 20:08:12 +0100 Subject: Add tests for ConstantEvaluator --- test/libsolidity/SolidityNameAndTypeResolution.cpp | 40 +++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index a6fc4e34..9972d795 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -7102,7 +7102,7 @@ BOOST_AUTO_TEST_CASE(address_overload_resolution) CHECK_SUCCESS(text); } -BOOST_AUTO_TEST_CASE(array_length_validation) +BOOST_AUTO_TEST_CASE(array_length_too_large) { char const* text = R"( contract C { @@ -7112,6 +7112,44 @@ BOOST_AUTO_TEST_CASE(array_length_validation) CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal."); } +BOOST_AUTO_TEST_CASE(array_length_not_convertible_to_integer) +{ + char const* text = R"( + contract C { + uint[true] ids; + } + )"; + CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal."); +} + +BOOST_AUTO_TEST_CASE(array_length_invalid_expression) +{ + char const* text = R"( + contract C { + uint[-true] ids; + } + )"; + CHECK_ERROR(text, TypeError, "Invalid constant expression."); + text = R"( + contract C { + uint[true/1] ids; + } + )"; + CHECK_ERROR(text, TypeError, "Invalid constant expression."); + text = R"( + contract C { + uint[1/true] ids; + } + )"; + CHECK_ERROR(text, TypeError, "Invalid constant expression."); + text = R"( + contract C { + uint[1.111111E1111111111111] ids; + } + )"; + CHECK_ERROR(text, TypeError, "Invalid literal value."); +} + BOOST_AUTO_TEST_CASE(no_address_members_on_contract) { char const* text = R"( -- cgit v1.2.3 From ed62b2583cf96a970dd610fa3ce837942bb67500 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 5 Oct 2017 20:17:54 +0100 Subject: Use the proper error reporting interface in ConstantEvaluator --- libsolidity/analysis/ConstantEvaluator.cpp | 10 +++++----- libsolidity/analysis/ConstantEvaluator.h | 8 +++++++- libsolidity/analysis/ReferencesResolver.cpp | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 7057eab7..6636ad97 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -22,17 +22,17 @@ #include #include +#include using namespace std; using namespace dev; using namespace dev::solidity; - void ConstantEvaluator::endVisit(UnaryOperation const& _operation) { TypePointer const& subType = _operation.subExpression().annotation().type; if (!dynamic_cast(subType.get())) - BOOST_THROW_EXCEPTION(_operation.subExpression().createTypeError("Invalid constant expression.")); + m_errorReporter.fatalTypeError(_operation.subExpression().location(), "Invalid constant expression."); TypePointer t = subType->unaryOperatorResult(_operation.getOperator()); _operation.annotation().type = t; } @@ -42,9 +42,9 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation) TypePointer const& leftType = _operation.leftExpression().annotation().type; TypePointer const& rightType = _operation.rightExpression().annotation().type; if (!dynamic_cast(leftType.get())) - BOOST_THROW_EXCEPTION(_operation.leftExpression().createTypeError("Invalid constant expression.")); + m_errorReporter.fatalTypeError(_operation.leftExpression().location(), "Invalid constant expression."); if (!dynamic_cast(rightType.get())) - BOOST_THROW_EXCEPTION(_operation.rightExpression().createTypeError("Invalid constant expression.")); + m_errorReporter.fatalTypeError(_operation.rightExpression().location(), "Invalid constant expression."); TypePointer commonType = leftType->binaryOperatorResult(_operation.getOperator(), rightType); if (Token::isCompareOp(_operation.getOperator())) commonType = make_shared(); @@ -55,5 +55,5 @@ void ConstantEvaluator::endVisit(Literal const& _literal) { _literal.annotation().type = Type::forLiteral(_literal); if (!_literal.annotation().type) - BOOST_THROW_EXCEPTION(_literal.createTypeError("Invalid literal value.")); + m_errorReporter.fatalTypeError(_literal.location(), "Invalid literal value."); } diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h index 9ec04ebe..90bceb5d 100644 --- a/libsolidity/analysis/ConstantEvaluator.h +++ b/libsolidity/analysis/ConstantEvaluator.h @@ -29,6 +29,7 @@ namespace dev namespace solidity { +class ErrorReporter; class TypeChecker; /** @@ -37,13 +38,18 @@ class TypeChecker; class ConstantEvaluator: private ASTConstVisitor { public: - ConstantEvaluator(Expression const& _expr) { _expr.accept(*this); } + ConstantEvaluator(Expression const& _expr, ErrorReporter& _errorReporter): + m_errorReporter(_errorReporter) + { + _expr.accept(*this); + } private: virtual void endVisit(BinaryOperation const& _operation); virtual void endVisit(UnaryOperation const& _operation); virtual void endVisit(Literal const& _literal); + ErrorReporter& m_errorReporter; }; } diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 29278332..f22c95cc 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -147,7 +147,7 @@ void ReferencesResolver::endVisit(ArrayTypeName const& _typeName) if (Expression const* length = _typeName.length()) { if (!length->annotation().type) - ConstantEvaluator e(*length); + ConstantEvaluator e(*length, m_errorReporter); auto const* lengthType = dynamic_cast(length->annotation().type.get()); if (!lengthType || !lengthType->mobileType()) fatalTypeError(length->location(), "Invalid array length, expected integer literal."); -- cgit v1.2.3 From 475b81880185e816db9a962a06cb3c323b953a90 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 5 Oct 2017 20:18:46 +0100 Subject: Remove obsolete createTypeError in AST --- libsolidity/ast/AST.cpp | 6 ------ libsolidity/ast/AST.h | 5 ----- libsolidity/ast/Types.cpp | 2 +- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index a805322b..1048b610 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -73,11 +72,6 @@ ASTAnnotation& ASTNode::annotation() const return *m_annotation; } -Error ASTNode::createTypeError(string const& _description) const -{ - return Error(Error::Type::TypeError) << errinfo_sourceLocation(location()) << errinfo_comment(_description); -} - SourceUnitAnnotation& SourceUnit::annotation() const { if (!m_annotation) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 75b8e946..733e7c78 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -89,10 +88,6 @@ public: /// Returns the source code location of this node. SourceLocation const& location() const { return m_location; } - /// Creates a @ref TypeError exception and decorates it with the location of the node and - /// the given description - Error createTypeError(std::string const& _description) const; - ///@todo make this const-safe by providing a different way to access the annotation virtual ASTAnnotation& annotation() const; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index ff5195ff..ee5f462b 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2025,7 +2025,7 @@ unsigned EnumType::memberValue(ASTString const& _member) const return index; ++index; } - BOOST_THROW_EXCEPTION(m_enum.createTypeError("Requested unknown enum value ." + _member)); + solAssert(false, "Requested unknown enum value " + _member); } bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const -- cgit v1.2.3