From df142782bc3a1435f70d9f5f4c8e04ae8d7e1678 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 15 Oct 2014 14:45:51 +0200 Subject: Added meaningful exception types. --- AST.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'AST.cpp') diff --git a/AST.cpp b/AST.cpp index 325ef50b..926f1c68 100644 --- a/AST.cpp +++ b/AST.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace dev { namespace solidity { @@ -245,7 +246,9 @@ void Literal::accept(ASTVisitor& _visitor) void Statement::expectType(Expression& _expression, const Type& _expectedType) { if (!_expression.checkTypeRequirements()->isImplicitlyConvertibleTo(_expectedType)) - throw std::exception(); // @todo + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type not implicitly convertible " + "to expected type.")); + //@todo provide more information to the exception } ptr Block::checkTypeRequirements() @@ -284,7 +287,9 @@ ptr Return::checkTypeRequirements() { BOOST_ASSERT(m_returnParameters != nullptr); if (m_returnParameters->getParameters().size() != 1) - throw std::exception(); // @todo + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Different number of arguments in " + "return statement than in returns " + "declaration.")); // this could later be changed such that the paramaters type is an anonymous struct type, // but for now, we only allow one return parameter @@ -318,7 +323,7 @@ ptr Assignment::checkTypeRequirements() if (m_assigmentOperator != Token::ASSIGN) { // complex assignment if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator))) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type.")); } return m_type; } @@ -328,7 +333,7 @@ ptr UnaryOperation::checkTypeRequirements() // INC, DEC, NOT, BIT_NOT, DELETE m_type = m_subExpression->checkTypeRequirements(); if (m_type->acceptsUnaryOperator(m_operator)) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Unary operator not compatible with type.")); return m_type; } @@ -342,7 +347,7 @@ ptr BinaryOperation::checkTypeRequirements() else if (m_left->getType()->isImplicitlyConvertibleTo(*m_right->getType())) m_commonType = m_right->getType(); else - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("No common type found in binary operation.")); if (Token::IsCompareOp(m_operator)) { m_type = std::make_shared(); @@ -350,7 +355,7 @@ ptr BinaryOperation::checkTypeRequirements() BOOST_ASSERT(Token::IsBinaryOp(m_operator)); m_type = m_commonType; if (!m_commonType->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_operator))) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type.")); } return m_type; } @@ -369,9 +374,11 @@ ptr FunctionCall::checkTypeRequirements() //@todo for structs, we have to check the number of arguments to be equal to the // number of non-mapping members if (m_arguments.size() != 1) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("More than one argument for " + "explicit type conersion.")); if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type->getActualType())) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Explicit type conversion not " + "allowed.")); m_type = type->getActualType(); } else if (category == Type::Category::FUNCTION) { //@todo would be nice to create a struct type from the arguments @@ -382,10 +389,12 @@ ptr FunctionCall::checkTypeRequirements() FunctionDefinition const& fun = function->getFunction(); vecptr const& parameters = fun.getParameters(); if (parameters.size() != m_arguments.size()) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for " + "function call.")); for (size_t i = 0; i < m_arguments.size(); ++i) { if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameters[i]->getType())) - throw std::exception(); + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Invalid type for argument in " + "function call.")); } // @todo actually the return type should be an anonymous struct, @@ -395,7 +404,7 @@ ptr FunctionCall::checkTypeRequirements() else m_type = fun.getReturnParameterList()->getParameters().front()->getType(); } else { - throw std::exception(); // type does not support invocation + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type does not support invocation.")); } return m_type; } @@ -428,7 +437,8 @@ ptr Identifier::checkTypeRequirements() VariableDeclaration* variable = dynamic_cast(m_referencedDeclaration); if (variable != nullptr) { if (variable->getType().get() == nullptr) - throw std::exception(); // variable used before type could be determined + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Variable referenced before type " + "could be determined.")); m_type = variable->getType(); return m_type; } @@ -452,7 +462,7 @@ ptr Identifier::checkTypeRequirements() m_type = std::make_shared(std::make_shared(*contractDef)); return m_type; } - throw std::exception(); // declaration reference of unknown/forbidden type + BOOST_ASSERT(false); // declaration reference of unknown/forbidden type return m_type; } -- cgit