aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-10-06 19:50:15 +0800
committerGitHub <noreply@github.com>2017-10-06 19:50:15 +0800
commit094012dbb046655ac0291f6c4632f306406c0ada (patch)
tree56f31dfd7a35727b7781db63253e7037395d8337
parent961f8746ffb169b564ac625a3cb0b215ec671757 (diff)
parent475b81880185e816db9a962a06cb3c323b953a90 (diff)
downloaddexon-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.cpp10
-rw-r--r--libsolidity/analysis/ConstantEvaluator.h8
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp2
-rw-r--r--libsolidity/ast/AST.cpp6
-rw-r--r--libsolidity/ast/AST.h5
-rw-r--r--libsolidity/ast/Types.cpp2
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp40
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"(