diff options
author | chriseth <chris@ethereum.org> | 2017-10-06 19:50:15 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-06 19:50:15 +0800 |
commit | 094012dbb046655ac0291f6c4632f306406c0ada (patch) | |
tree | 56f31dfd7a35727b7781db63253e7037395d8337 | |
parent | 961f8746ffb169b564ac625a3cb0b215ec671757 (diff) | |
parent | 475b81880185e816db9a962a06cb3c323b953a90 (diff) | |
download | dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.tar dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.tar.gz dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.tar.bz2 dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.tar.lz dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.tar.xz dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.tar.zst dexon-solidity-094012dbb046655ac0291f6c4632f306406c0ada.zip |
Merge pull request #3036 from ethereum/constant-eval-refactor
Refactor error reporting in ConstantEvaluator
-rw-r--r-- | libsolidity/analysis/ConstantEvaluator.cpp | 10 | ||||
-rw-r--r-- | libsolidity/analysis/ConstantEvaluator.h | 8 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 2 | ||||
-rw-r--r-- | libsolidity/ast/AST.cpp | 6 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 5 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 40 |
7 files changed, 53 insertions, 20 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 <libsolidity/analysis/ConstantEvaluator.h> #include <libsolidity/ast/AST.h> +#include <libsolidity/interface/ErrorReporter.h> 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<RationalNumberType const*>(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<RationalNumberType const*>(leftType.get())) - BOOST_THROW_EXCEPTION(_operation.leftExpression().createTypeError("Invalid constant expression.")); + m_errorReporter.fatalTypeError(_operation.leftExpression().location(), "Invalid constant expression."); if (!dynamic_cast<RationalNumberType const*>(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<BoolType>(); @@ -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<RationalNumberType const*>(length->annotation().type.get()); if (!lengthType || !lengthType->mobileType()) fatalTypeError(length->location(), "Invalid array length, expected integer literal."); 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 <libsolidity/ast/AST.h> #include <libsolidity/ast/ASTVisitor.h> -#include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/AST_accept.h> #include <libdevcore/SHA3.h> @@ -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 <libsolidity/ast/ASTForward.h> #include <libsolidity/parsing/Token.h> #include <libsolidity/ast/Types.h> -#include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/ASTAnnotations.h> #include <libsolidity/ast/ASTEnums.h> @@ -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 diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index c3dacc3d..903e7308 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -7122,7 +7122,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 { @@ -7132,6 +7132,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"( |