Browse Source

Merge pull request #640 from chriseth/sol_solAssert

Assertions that throw InternalCompilerErrors.
cl-refactor
chriseth 10 years ago
parent
commit
d836140a5e
  1. 8
      libsolidity/AST.cpp
  2. 16
      libsolidity/AST.h
  3. 20
      libsolidity/CompilerContext.cpp
  4. 6
      libsolidity/CompilerUtils.cpp
  5. 33
      libsolidity/ExpressionCompiler.cpp
  6. 3
      libsolidity/InterfaceHandler.cpp
  7. 15
      libsolidity/NameAndTypeResolver.cpp
  8. 13
      libsolidity/Scanner.cpp
  9. 13
      libsolidity/Token.h
  10. 13
      libsolidity/Types.cpp
  11. 49
      libsolidity/Utils.h
  12. 29
      solc/CommandLineInterface.cpp

8
libsolidity/AST.cpp

@ -21,7 +21,7 @@
*/ */
#include <algorithm> #include <algorithm>
#include <libsolidity/Utils.h>
#include <libsolidity/AST.h> #include <libsolidity/AST.h>
#include <libsolidity/ASTVisitor.h> #include <libsolidity/ASTVisitor.h>
#include <libsolidity/Exceptions.h> #include <libsolidity/Exceptions.h>
@ -145,8 +145,7 @@ void Return::checkTypeRequirements()
{ {
if (!m_expression) if (!m_expression)
return; return;
if (asserts(m_returnParameters)) solAssert(m_returnParameters, "Return parameters not assigned.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Return parameters not assigned."));
if (m_returnParameters->getParameters().size() != 1) if (m_returnParameters->getParameters().size() != 1)
BOOST_THROW_EXCEPTION(createTypeError("Different number of arguments in return statement " BOOST_THROW_EXCEPTION(createTypeError("Different number of arguments in return statement "
"than in returns declaration.")); "than in returns declaration."));
@ -336,8 +335,7 @@ void IndexAccess::checkTypeRequirements()
void Identifier::checkTypeRequirements() void Identifier::checkTypeRequirements()
{ {
if (asserts(m_referencedDeclaration)) solAssert(m_referencedDeclaration, "Identifier not resolved.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier not resolved."));
VariableDeclaration const* variable = dynamic_cast<VariableDeclaration const*>(m_referencedDeclaration); VariableDeclaration const* variable = dynamic_cast<VariableDeclaration const*>(m_referencedDeclaration);
if (variable) if (variable)

16
libsolidity/AST.h

@ -27,6 +27,7 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <libsolidity/Utils.h>
#include <libsolidity/ASTForward.h> #include <libsolidity/ASTForward.h>
#include <libsolidity/BaseTypes.h> #include <libsolidity/BaseTypes.h>
#include <libsolidity/Token.h> #include <libsolidity/Token.h>
@ -364,7 +365,7 @@ public:
explicit ElementaryTypeName(Location const& _location, Token::Value _type): explicit ElementaryTypeName(Location const& _location, Token::Value _type):
TypeName(_location), m_type(_type) TypeName(_location), m_type(_type)
{ {
if (asserts(Token::isElementaryTypeName(_type))) BOOST_THROW_EXCEPTION(InternalCompilerError()); solAssert(Token::isElementaryTypeName(_type), "");
} }
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
@ -575,8 +576,7 @@ public:
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; } void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
ParameterList const& getFunctionReturnParameters() const ParameterList const& getFunctionReturnParameters() const
{ {
if (asserts(m_returnParameters)) solAssert(m_returnParameters, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
return *m_returnParameters; return *m_returnParameters;
} }
Expression const* getExpression() const { return m_expression.get(); } Expression const* getExpression() const { return m_expression.get(); }
@ -682,7 +682,7 @@ public:
Expression(_location), m_leftHandSide(_leftHandSide), Expression(_location), m_leftHandSide(_leftHandSide),
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide)
{ {
if (asserts(Token::isAssignmentOp(_assignmentOperator))) BOOST_THROW_EXCEPTION(InternalCompilerError()); solAssert(Token::isAssignmentOp(_assignmentOperator), "");
} }
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
@ -710,7 +710,7 @@ public:
Expression(_location), m_operator(_operator), Expression(_location), m_operator(_operator),
m_subExpression(_subExpression), m_isPrefix(_isPrefix) m_subExpression(_subExpression), m_isPrefix(_isPrefix)
{ {
if (asserts(Token::isUnaryOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError()); solAssert(Token::isUnaryOp(_operator), "");
} }
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
@ -737,7 +737,7 @@ public:
Token::Value _operator, ASTPointer<Expression> const& _right): Token::Value _operator, ASTPointer<Expression> const& _right):
Expression(_location), m_left(_left), m_operator(_operator), m_right(_right) Expression(_location), m_left(_left), m_operator(_operator), m_right(_right)
{ {
if (asserts(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError()); solAssert(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator), "");
} }
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
@ -799,7 +799,7 @@ public:
std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; }
/// Returns the referenced contract. Can only be called after type checking. /// Returns the referenced contract. Can only be called after type checking.
ContractDefinition const* getContract() const { if (asserts(m_contract)) BOOST_THROW_EXCEPTION(InternalCompilerError()); else return m_contract; } ContractDefinition const* getContract() const { solAssert(m_contract, ""); return m_contract; }
private: private:
ASTPointer<Identifier> m_contractName; ASTPointer<Identifier> m_contractName;
@ -894,7 +894,7 @@ public:
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken): ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken):
PrimaryExpression(_location), m_typeToken(_typeToken) PrimaryExpression(_location), m_typeToken(_typeToken)
{ {
if (asserts(Token::isElementaryTypeName(_typeToken))) BOOST_THROW_EXCEPTION(InternalCompilerError()); solAssert(Token::isElementaryTypeName(_typeToken), "");
} }
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;

20
libsolidity/CompilerContext.cpp

@ -27,8 +27,10 @@
using namespace std; using namespace std;
namespace dev { namespace dev
namespace solidity { {
namespace solidity
{
void CompilerContext::addMagicGlobal(MagicVariableDeclaration const& _declaration) void CompilerContext::addMagicGlobal(MagicVariableDeclaration const& _declaration)
{ {
@ -65,8 +67,7 @@ void CompilerContext::addFunction(FunctionDefinition const& _function)
bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _contract) const bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _contract) const
{ {
auto ret = m_compiledContracts.find(&_contract); auto ret = m_compiledContracts.find(&_contract);
if (asserts(ret != m_compiledContracts.end())) solAssert(ret != m_compiledContracts.end(), "Compiled contract not found.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Compiled contract not found."));
return *ret->second; return *ret->second;
} }
@ -78,16 +79,14 @@ bool CompilerContext::isLocalVariable(Declaration const* _declaration) const
eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const
{ {
auto res = m_functionEntryLabels.find(&_function); auto res = m_functionEntryLabels.find(&_function);
if (asserts(res != m_functionEntryLabels.end())) solAssert(res != m_functionEntryLabels.end(), "Function entry label not found.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Function entry label not found."));
return res->second.tag(); return res->second.tag();
} }
unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const
{ {
auto res = m_localVariables.find(&_declaration); auto res = m_localVariables.find(&_declaration);
if (asserts(res != m_localVariables.end())) solAssert(res != m_localVariables.end(), "Variable not found on stack.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack."));
return m_localVariablesSize - res->second - 1; return m_localVariablesSize - res->second - 1;
} }
@ -99,12 +98,9 @@ unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const
u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const
{ {
auto it = m_stateVariables.find(&_declaration); auto it = m_stateVariables.find(&_declaration);
if (it == m_stateVariables.end()) solAssert(it != m_stateVariables.end(), "Variable not found in storage.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found in storage."));
return it->second; return it->second;
} }
} }
} }

6
libsolidity/CompilerUtils.cpp

@ -39,8 +39,7 @@ void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _left
return; return;
} }
eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD;
if (asserts(_bytes <= 32)) solAssert(_bytes <= 32, "Memory load of more than 32 bytes requested.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of more than 32 bytes requested."));
if (_bytes == 32) if (_bytes == 32)
m_context << u256(_offset) << load; m_context << u256(_offset) << load;
else else
@ -63,8 +62,7 @@ void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftA
m_context << eth::Instruction::POP; m_context << eth::Instruction::POP;
return; return;
} }
if (asserts(_bytes <= 32)) solAssert(_bytes <= 32, "Memory store of more than 32 bytes requested.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of more than 32 bytes requested."));
if (_bytes != 32 && !_leftAligned) if (_bytes != 32 && !_leftAligned)
// shift the value accordingly before storing // shift the value accordingly before storing
m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL; m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL;

33
libsolidity/ExpressionCompiler.cpp

@ -30,8 +30,10 @@
using namespace std; using namespace std;
namespace dev { namespace dev
namespace solidity { {
namespace solidity
{
void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize) void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize)
{ {
@ -51,8 +53,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
_assignment.getRightHandSide().accept(*this); _assignment.getRightHandSide().accept(*this);
appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType()); appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
_assignment.getLeftHandSide().accept(*this); _assignment.getLeftHandSide().accept(*this);
if (asserts(m_currentLValue.isValid())) solAssert(m_currentLValue.isValid(), "LValue not retrieved.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
Token::Value op = _assignment.getAssignmentOperator(); Token::Value op = _assignment.getAssignmentOperator();
if (op != Token::ASSIGN) // compound assignment if (op != Token::ASSIGN) // compound assignment
@ -84,8 +85,7 @@ void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation)
break; break;
case Token::DELETE: // delete case Token::DELETE: // delete
// @todo semantics change for complex types // @todo semantics change for complex types
if (asserts(m_currentLValue.isValid())) solAssert(m_currentLValue.isValid(), "LValue not retrieved.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
m_context << u256(0); m_context << u256(0);
if (m_currentLValue.storesReferenceOnStack()) if (m_currentLValue.storesReferenceOnStack())
@ -95,8 +95,7 @@ void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation)
break; break;
case Token::INC: // ++ (pre- or postfix) case Token::INC: // ++ (pre- or postfix)
case Token::DEC: // -- (pre- or postfix) case Token::DEC: // -- (pre- or postfix)
if (asserts(m_currentLValue.isValid())) solAssert(m_currentLValue.isValid(), "LValue not retrieved.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
m_currentLValue.retrieveValue(_unaryOperation); m_currentLValue.retrieveValue(_unaryOperation);
if (!_unaryOperation.isPrefixOperation()) if (!_unaryOperation.isPrefixOperation())
{ {
@ -179,8 +178,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
if (_functionCall.isTypeConversion()) if (_functionCall.isTypeConversion())
{ {
//@todo struct construction //@todo struct construction
if (asserts(_functionCall.getArguments().size() == 1)) solAssert(_functionCall.getArguments().size() == 1, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
Expression const& firstArgument = *_functionCall.getArguments().front(); Expression const& firstArgument = *_functionCall.getArguments().front();
firstArgument.accept(*this); firstArgument.accept(*this);
if (firstArgument.getType()->getCategory() == Type::Category::CONTRACT && if (firstArgument.getType()->getCategory() == Type::Category::CONTRACT &&
@ -195,8 +193,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{ {
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType()); FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments(); vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments();
if (asserts(arguments.size() == function.getParameterTypes().size())) solAssert(arguments.size() == function.getParameterTypes().size(), "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
switch (function.getLocation()) switch (function.getLocation())
{ {
@ -282,12 +279,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
bool ExpressionCompiler::visit(NewExpression const& _newExpression) bool ExpressionCompiler::visit(NewExpression const& _newExpression)
{ {
ContractType const* type = dynamic_cast<ContractType const*>(_newExpression.getType().get()); ContractType const* type = dynamic_cast<ContractType const*>(_newExpression.getType().get());
if (asserts(type)) solAssert(type, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
TypePointers const& types = type->getConstructorType()->getParameterTypes(); TypePointers const& types = type->getConstructorType()->getParameterTypes();
vector<ASTPointer<Expression const>> arguments = _newExpression.getArguments(); vector<ASTPointer<Expression const>> arguments = _newExpression.getArguments();
if (asserts(arguments.size() == types.size())) solAssert(arguments.size() == types.size(), "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
// copy the contracts code into memory // copy the contracts code into memory
bytes const& bytecode = m_context.getCompiledContract(*_newExpression.getContract()); bytes const& bytecode = m_context.getCompiledContract(*_newExpression.getContract());
@ -439,8 +434,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal)
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation) void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation)
{ {
Token::Value const op = _binaryOperation.getOperator(); Token::Value const op = _binaryOperation.getOperator();
if (asserts(op == Token::OR || op == Token::AND)) solAssert(op == Token::OR || op == Token::AND, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
_binaryOperation.getLeftExpression().accept(*this); _binaryOperation.getLeftExpression().accept(*this);
m_context << eth::Instruction::DUP1; m_context << eth::Instruction::DUP1;
@ -592,8 +586,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
vector<ASTPointer<Expression const>> const& _arguments, vector<ASTPointer<Expression const>> const& _arguments,
FunctionCallOptions const& _options) FunctionCallOptions const& _options)
{ {
if (asserts(_arguments.size() == _functionType.getParameterTypes().size())) solAssert(_arguments.size() == _functionType.getParameterTypes().size(), "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
unsigned dataOffset = _options.bare ? 0 : 1; // reserve one byte for the function index unsigned dataOffset = _options.bare ? 0 : 1; // reserve one byte for the function index
for (unsigned i = 0; i < _arguments.size(); ++i) for (unsigned i = 0; i < _arguments.size(); ++i)

3
libsolidity/InterfaceHandler.cpp

@ -198,8 +198,7 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con
std::string::const_iterator _end) std::string::const_iterator _end)
{ {
// Should never be called with an empty vector // Should never be called with an empty vector
if (asserts(!m_params.empty())) solAssert(!m_params.empty(), "Internal: Tried to append to empty parameter");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Tried to append to empty parameter"));
auto pair = m_params.back(); auto pair = m_params.back();
pair.second += " "; pair.second += " ";

15
libsolidity/NameAndTypeResolver.cpp

@ -70,8 +70,7 @@ void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract)
void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
{ {
m_scopes[nullptr].registerDeclaration(_declaration, true); m_scopes[nullptr].registerDeclaration(_declaration, true);
if (asserts(_declaration.getScope() == nullptr)) solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Updated declaration outside global scope."));
} }
Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
@ -133,8 +132,7 @@ void DeclarationRegistrationHelper::endVisit(VariableDefinition& _variableDefini
{ {
// Register the local variables with the function // Register the local variables with the function
// This does not fit here perfectly, but it saves us another AST visit. // This does not fit here perfectly, but it saves us another AST visit.
if (asserts(m_currentFunction)) solAssert(m_currentFunction, "Variable definition without function.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable definition without function."));
m_currentFunction->addLocalVariable(_variableDefinition.getDeclaration()); m_currentFunction->addLocalVariable(_variableDefinition.getDeclaration());
} }
@ -149,15 +147,13 @@ void DeclarationRegistrationHelper::enterNewSubScope(Declaration const& _declara
map<ASTNode const*, DeclarationContainer>::iterator iter; map<ASTNode const*, DeclarationContainer>::iterator iter;
bool newlyAdded; bool newlyAdded;
tie(iter, newlyAdded) = m_scopes.emplace(&_declaration, DeclarationContainer(m_currentScope, &m_scopes[m_currentScope])); tie(iter, newlyAdded) = m_scopes.emplace(&_declaration, DeclarationContainer(m_currentScope, &m_scopes[m_currentScope]));
if (asserts(newlyAdded)) solAssert(newlyAdded, "Unable to add new scope.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to add new scope."));
m_currentScope = &_declaration; m_currentScope = &_declaration;
} }
void DeclarationRegistrationHelper::closeCurrentScope() void DeclarationRegistrationHelper::closeCurrentScope()
{ {
if (asserts(m_currentScope)) solAssert(m_currentScope, "Closed non-existing scope.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Closed non-existing scope."));
m_currentScope = m_scopes[m_currentScope].getEnclosingDeclaration(); m_currentScope = m_scopes[m_currentScope].getEnclosingDeclaration();
} }
@ -196,8 +192,7 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable)
bool ReferencesResolver::visit(Return& _return) bool ReferencesResolver::visit(Return& _return)
{ {
if (asserts(m_returnParameters)) solAssert(m_returnParameters, "Return parameters not set.");
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Return parameters not set."));
_return.setFunctionReturnParameters(*m_returnParameters); _return.setFunctionReturnParameters(*m_returnParameters);
return true; return true;
} }

13
libsolidity/Scanner.cpp

@ -52,6 +52,7 @@
#include <algorithm> #include <algorithm>
#include <tuple> #include <tuple>
#include <libsolidity/Utils.h>
#include <libsolidity/Scanner.h> #include <libsolidity/Scanner.h>
using namespace std; using namespace std;
@ -249,8 +250,7 @@ Token::Value Scanner::scanDocumentationComment()
Token::Value Scanner::skipMultiLineComment() Token::Value Scanner::skipMultiLineComment()
{ {
if (asserts(m_char == '*')) solAssert(m_char == '*', "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
advance(); advance();
while (!isSourcePastEndOfInput()) while (!isSourcePastEndOfInput())
{ {
@ -597,8 +597,7 @@ Token::Value Scanner::scanNumber(char _charSeen)
// scan exponent, if any // scan exponent, if any
if (m_char == 'e' || m_char == 'E') if (m_char == 'e' || m_char == 'E')
{ {
if (asserts(kind != HEX)) // 'e'/'E' must be scanned as part of the hex number solAssert(kind != HEX, "'e'/'E' must be scanned as part of the hex number");
BOOST_THROW_EXCEPTION(InternalCompilerError());
if (kind != DECIMAL) if (kind != DECIMAL)
return Token::ILLEGAL; return Token::ILLEGAL;
// scan exponent // scan exponent
@ -639,8 +638,7 @@ static Token::Value keywordOrIdentifierToken(string const& _input)
Token::Value Scanner::scanIdentifierOrKeyword() Token::Value Scanner::scanIdentifierOrKeyword()
{ {
if (asserts(isIdentifierStart(m_char))) solAssert(isIdentifierStart(m_char), "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
LiteralScope literal(this, LITERAL_TYPE_STRING); LiteralScope literal(this, LITERAL_TYPE_STRING);
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
// Scan the rest of the identifier characters. // Scan the rest of the identifier characters.
@ -662,8 +660,7 @@ char CharStream::advanceAndGet(size_t _chars)
char CharStream::rollback(size_t _amount) char CharStream::rollback(size_t _amount)
{ {
if (asserts(m_pos >= _amount)) solAssert(m_pos >= _amount, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
m_pos -= _amount; m_pos -= _amount;
return get(); return get();
} }

13
libsolidity/Token.h

@ -44,6 +44,7 @@
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libsolidity/Utils.h>
#include <libsolidity/Exceptions.h> #include <libsolidity/Exceptions.h>
namespace dev namespace dev
@ -344,8 +345,7 @@ public:
// (e.g. "LT" for the token LT). // (e.g. "LT" for the token LT).
static char const* getName(Value tok) static char const* getName(Value tok)
{ {
if (asserts(tok < NUM_TOKENS)) solAssert(tok < NUM_TOKENS, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
return m_name[tok]; return m_name[tok];
} }
@ -360,8 +360,7 @@ public:
static Value AssignmentToBinaryOp(Value op) static Value AssignmentToBinaryOp(Value op)
{ {
if (asserts(isAssignmentOp(op) && op != ASSIGN)) solAssert(isAssignmentOp(op) && op != ASSIGN, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
return Token::Value(op + (BIT_OR - ASSIGN_BIT_OR)); return Token::Value(op + (BIT_OR - ASSIGN_BIT_OR));
} }
@ -375,8 +374,7 @@ public:
// have a (unique) string (e.g. an IDENTIFIER). // have a (unique) string (e.g. an IDENTIFIER).
static char const* toString(Value tok) static char const* toString(Value tok)
{ {
if (asserts(tok < NUM_TOKENS)) solAssert(tok < NUM_TOKENS, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
return m_string[tok]; return m_string[tok];
} }
@ -384,8 +382,7 @@ public:
// operators; returns 0 otherwise. // operators; returns 0 otherwise.
static int precedence(Value tok) static int precedence(Value tok)
{ {
if (asserts(tok < NUM_TOKENS)) solAssert(tok < NUM_TOKENS, "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
return m_precedence[tok]; return m_precedence[tok];
} }

13
libsolidity/Types.cpp

@ -22,6 +22,7 @@
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libsolidity/Utils.h>
#include <libsolidity/Types.h> #include <libsolidity/Types.h>
#include <libsolidity/AST.h> #include <libsolidity/AST.h>
@ -34,8 +35,7 @@ namespace solidity
shared_ptr<Type const> Type::fromElementaryTypeName(Token::Value _typeToken) shared_ptr<Type const> Type::fromElementaryTypeName(Token::Value _typeToken)
{ {
if (asserts(Token::isElementaryTypeName(_typeToken))) solAssert(Token::isElementaryTypeName(_typeToken), "");
BOOST_THROW_EXCEPTION(InternalCompilerError());
if (Token::INT <= _typeToken && _typeToken <= Token::HASH256) if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
{ {
@ -120,8 +120,8 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
{ {
if (isAddress()) if (isAddress())
m_bits = 160; m_bits = 160;
if (asserts(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0)) solAssert(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0,
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid bit number for integer type: " + dev::toString(_bits))); "Invalid bit number for integer type: " + dev::toString(_bits));
} }
bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
@ -215,9 +215,8 @@ shared_ptr<StaticStringType> StaticStringType::smallestTypeForLiteral(string con
StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes) StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes)
{ {
if (asserts(m_bytes >= 0 && m_bytes <= 32)) solAssert(m_bytes >= 0 && m_bytes <= 32,
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " + "Invalid byte number for static string type: " + dev::toString(m_bytes));
dev::toString(m_bytes)));
} }
bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const

49
libsolidity/Utils.h

@ -0,0 +1,49 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
* @date 2014
* Solidity Utilities.
*/
#pragma once
#include <string>
#include <libsolidity/Exceptions.h>
namespace dev
{
namespace solidity
{
/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
#define solAssert(CONDITION, DESCRIPTION) \
::dev::solidity::solAssertAux(CONDITION, DESCRIPTION, __LINE__, __FILE__, ETH_FUNC)
inline void solAssertAux(bool _condition, std::string const& _errorDescription, unsigned _line,
char const* _file, char const* _function)
{
if (!_condition)
::boost::throw_exception( InternalCompilerError()
<< errinfo_comment(_errorDescription)
<< ::boost::throw_function(_function)
<< ::boost::throw_file(_file)
<< ::boost::throw_line(_line));
}
}
}

29
solc/CommandLineInterface.cpp

@ -230,9 +230,9 @@ bool CommandLineInterface::parseArguments(int argc, char** argv)
{ {
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args); po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args);
} }
catch (po::error const& exception) catch (po::error const& _exception)
{ {
cout << exception.what() << endl; cout << _exception.what() << endl;
return false; return false;
} }
po::notify(m_args); po::notify(m_args);
@ -289,34 +289,35 @@ bool CommandLineInterface::processInput()
// TODO: Perhaps we should not compile unless requested // TODO: Perhaps we should not compile unless requested
m_compiler.compile(m_args["optimize"].as<bool>()); m_compiler.compile(m_args["optimize"].as<bool>());
} }
catch (ParserError const& exception) catch (ParserError const& _exception)
{ {
SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Parser error", m_compiler); SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Parser error", m_compiler);
return false; return false;
} }
catch (DeclarationError const& exception) catch (DeclarationError const& _exception)
{ {
SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Declaration error", m_compiler); SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Declaration error", m_compiler);
return false; return false;
} }
catch (TypeError const& exception) catch (TypeError const& _exception)
{ {
SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Type error", m_compiler); SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Type error", m_compiler);
return false; return false;
} }
catch (CompilerError const& exception) catch (CompilerError const& _exception)
{ {
SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Compiler error", m_compiler); SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", m_compiler);
return false; return false;
} }
catch (InternalCompilerError const& exception) catch (InternalCompilerError const& _exception)
{ {
SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Internal compiler error", m_compiler); cerr << "Internal compiler error during compilation:" << endl
<< boost::diagnostic_information(_exception);
return false; return false;
} }
catch (Exception const& exception) catch (Exception const& _exception)
{ {
cerr << "Exception during compilation: " << boost::diagnostic_information(exception) << endl; cerr << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl;
return false; return false;
} }
catch (...) catch (...)

Loading…
Cancel
Save