mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
throw statement implementation
This commit is contained in:
parent
9d43f2c186
commit
279a36b6f8
@ -968,6 +968,18 @@ private:
|
|||||||
ParameterList const* m_returnParameters;
|
ParameterList const* m_returnParameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The Throw statement to throw that triggers a solidity exception(jump to ErrorTag)
|
||||||
|
*/
|
||||||
|
class Throw: public Statement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Throw(SourceLocation const& _location): Statement(_location) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
virtual void checkTypeRequirements() override{};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of a variable as a statement inside a function. It requires a type name (which can
|
* Definition of a variable as a statement inside a function. It requires a type name (which can
|
||||||
* also be "var") but the actual assignment can be missing.
|
* also be "var") but the actual assignment can be missing.
|
||||||
|
@ -64,6 +64,7 @@ class ForStatement;
|
|||||||
class Continue;
|
class Continue;
|
||||||
class Break;
|
class Break;
|
||||||
class Return;
|
class Return;
|
||||||
|
class Throw;
|
||||||
class VariableDeclarationStatement;
|
class VariableDeclarationStatement;
|
||||||
class ExpressionStatement;
|
class ExpressionStatement;
|
||||||
class Expression;
|
class Expression;
|
||||||
|
@ -193,6 +193,12 @@ bool ASTJsonConverter::visit(Return const&)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTJsonConverter::visit(Throw const&)
|
||||||
|
{
|
||||||
|
addJsonNode("Throw", {}, true);;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ASTJsonConverter::visit(VariableDeclarationStatement const&)
|
bool ASTJsonConverter::visit(VariableDeclarationStatement const&)
|
||||||
{
|
{
|
||||||
addJsonNode("VariableDefinition", {}, true);
|
addJsonNode("VariableDefinition", {}, true);
|
||||||
@ -364,6 +370,11 @@ void ASTJsonConverter::endVisit(Return const&)
|
|||||||
goUp();
|
goUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ASTJsonConverter::endVisit(Throw const&)
|
||||||
|
{
|
||||||
|
goUp();
|
||||||
|
}
|
||||||
|
|
||||||
void ASTJsonConverter::endVisit(VariableDeclarationStatement const&)
|
void ASTJsonConverter::endVisit(VariableDeclarationStatement const&)
|
||||||
{
|
{
|
||||||
goUp();
|
goUp();
|
||||||
|
@ -63,6 +63,7 @@ public:
|
|||||||
bool visit(Continue const& _node) override;
|
bool visit(Continue const& _node) override;
|
||||||
bool visit(Break const& _node) override;
|
bool visit(Break const& _node) override;
|
||||||
bool visit(Return const& _node) override;
|
bool visit(Return const& _node) override;
|
||||||
|
bool visit(Throw const& _node) override;
|
||||||
bool visit(VariableDeclarationStatement const& _node) override;
|
bool visit(VariableDeclarationStatement const& _node) override;
|
||||||
bool visit(ExpressionStatement const& _node) override;
|
bool visit(ExpressionStatement const& _node) override;
|
||||||
bool visit(Assignment const& _node) override;
|
bool visit(Assignment const& _node) override;
|
||||||
@ -93,6 +94,7 @@ public:
|
|||||||
void endVisit(Continue const&) override;
|
void endVisit(Continue const&) override;
|
||||||
void endVisit(Break const&) override;
|
void endVisit(Break const&) override;
|
||||||
void endVisit(Return const&) override;
|
void endVisit(Return const&) override;
|
||||||
|
void endVisit(Throw const&) override;
|
||||||
void endVisit(VariableDeclarationStatement const&) override;
|
void endVisit(VariableDeclarationStatement const&) override;
|
||||||
void endVisit(ExpressionStatement const&) override;
|
void endVisit(ExpressionStatement const&) override;
|
||||||
void endVisit(Assignment const&) override;
|
void endVisit(Assignment const&) override;
|
||||||
|
@ -221,6 +221,13 @@ bool ASTPrinter::visit(Return const& _node)
|
|||||||
return goDeeper();
|
return goDeeper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Throw const& _node)
|
||||||
|
{
|
||||||
|
writeLine("Throw");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
bool ASTPrinter::visit(VariableDeclarationStatement const& _node)
|
bool ASTPrinter::visit(VariableDeclarationStatement const& _node)
|
||||||
{
|
{
|
||||||
writeLine("VariableDeclarationStatement");
|
writeLine("VariableDeclarationStatement");
|
||||||
@ -444,6 +451,11 @@ void ASTPrinter::endVisit(Return const&)
|
|||||||
m_indentation--;
|
m_indentation--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Throw const&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
void ASTPrinter::endVisit(VariableDeclarationStatement const&)
|
void ASTPrinter::endVisit(VariableDeclarationStatement const&)
|
||||||
{
|
{
|
||||||
m_indentation--;
|
m_indentation--;
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
bool visit(Continue const& _node) override;
|
bool visit(Continue const& _node) override;
|
||||||
bool visit(Break const& _node) override;
|
bool visit(Break const& _node) override;
|
||||||
bool visit(Return const& _node) override;
|
bool visit(Return const& _node) override;
|
||||||
|
bool visit(Throw const& _node) override;
|
||||||
bool visit(VariableDeclarationStatement const& _node) override;
|
bool visit(VariableDeclarationStatement const& _node) override;
|
||||||
bool visit(ExpressionStatement const& _node) override;
|
bool visit(ExpressionStatement const& _node) override;
|
||||||
bool visit(Assignment const& _node) override;
|
bool visit(Assignment const& _node) override;
|
||||||
@ -110,6 +111,7 @@ public:
|
|||||||
void endVisit(Continue const&) override;
|
void endVisit(Continue const&) override;
|
||||||
void endVisit(Break const&) override;
|
void endVisit(Break const&) override;
|
||||||
void endVisit(Return const&) override;
|
void endVisit(Return const&) override;
|
||||||
|
void endVisit(Throw const&) override;
|
||||||
void endVisit(VariableDeclarationStatement const&) override;
|
void endVisit(VariableDeclarationStatement const&) override;
|
||||||
void endVisit(ExpressionStatement const&) override;
|
void endVisit(ExpressionStatement const&) override;
|
||||||
void endVisit(Assignment const&) override;
|
void endVisit(Assignment const&) override;
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
virtual bool visit(Continue& _node) { return visitNode(_node); }
|
virtual bool visit(Continue& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(Break& _node) { return visitNode(_node); }
|
virtual bool visit(Break& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(Return& _node) { return visitNode(_node); }
|
virtual bool visit(Return& _node) { return visitNode(_node); }
|
||||||
|
virtual bool visit(Throw& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(VariableDeclarationStatement& _node) { return visitNode(_node); }
|
virtual bool visit(VariableDeclarationStatement& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(ExpressionStatement& _node) { return visitNode(_node); }
|
virtual bool visit(ExpressionStatement& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(Assignment& _node) { return visitNode(_node); }
|
virtual bool visit(Assignment& _node) { return visitNode(_node); }
|
||||||
@ -108,6 +109,7 @@ public:
|
|||||||
virtual void endVisit(Continue& _node) { endVisitNode(_node); }
|
virtual void endVisit(Continue& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(Break& _node) { endVisitNode(_node); }
|
virtual void endVisit(Break& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(Return& _node) { endVisitNode(_node); }
|
virtual void endVisit(Return& _node) { endVisitNode(_node); }
|
||||||
|
virtual void endVisit(Throw& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(VariableDeclarationStatement& _node) { endVisitNode(_node); }
|
virtual void endVisit(VariableDeclarationStatement& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(ExpressionStatement& _node) { endVisitNode(_node); }
|
virtual void endVisit(ExpressionStatement& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(Assignment& _node) { endVisitNode(_node); }
|
virtual void endVisit(Assignment& _node) { endVisitNode(_node); }
|
||||||
@ -159,6 +161,7 @@ public:
|
|||||||
virtual bool visit(Continue const& _node) { return visitNode(_node); }
|
virtual bool visit(Continue const& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(Break const& _node) { return visitNode(_node); }
|
virtual bool visit(Break const& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(Return const& _node) { return visitNode(_node); }
|
virtual bool visit(Return const& _node) { return visitNode(_node); }
|
||||||
|
virtual bool visit(Throw const& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(VariableDeclarationStatement const& _node) { return visitNode(_node); }
|
virtual bool visit(VariableDeclarationStatement const& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(ExpressionStatement const& _node) { return visitNode(_node); }
|
virtual bool visit(ExpressionStatement const& _node) { return visitNode(_node); }
|
||||||
virtual bool visit(Assignment const& _node) { return visitNode(_node); }
|
virtual bool visit(Assignment const& _node) { return visitNode(_node); }
|
||||||
@ -198,6 +201,7 @@ public:
|
|||||||
virtual void endVisit(Continue const& _node) { endVisitNode(_node); }
|
virtual void endVisit(Continue const& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(Break const& _node) { endVisitNode(_node); }
|
virtual void endVisit(Break const& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(Return const& _node) { endVisitNode(_node); }
|
virtual void endVisit(Return const& _node) { endVisitNode(_node); }
|
||||||
|
virtual void endVisit(Throw const& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(VariableDeclarationStatement const& _node) { endVisitNode(_node); }
|
virtual void endVisit(VariableDeclarationStatement const& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(ExpressionStatement const& _node) { endVisitNode(_node); }
|
virtual void endVisit(ExpressionStatement const& _node) { endVisitNode(_node); }
|
||||||
virtual void endVisit(Assignment const& _node) { endVisitNode(_node); }
|
virtual void endVisit(Assignment const& _node) { endVisitNode(_node); }
|
||||||
|
@ -491,6 +491,18 @@ void Return::accept(ASTConstVisitor& _visitor) const
|
|||||||
_visitor.endVisit(*this);
|
_visitor.endVisit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Throw::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this))
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Throw::accept(ASTConstVisitor& _visitor) const
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this))
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void ExpressionStatement::accept(ASTVisitor& _visitor)
|
void ExpressionStatement::accept(ASTVisitor& _visitor)
|
||||||
{
|
{
|
||||||
if (_visitor.visit(*this))
|
if (_visitor.visit(*this))
|
||||||
|
@ -606,6 +606,13 @@ bool Compiler::visit(Return const& _return)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Compiler::visit(Throw const& _throw)
|
||||||
|
{
|
||||||
|
CompilerContext::LocationSetter locationSetter(m_context, _throw);
|
||||||
|
m_context.appendJumpTo(m_context.errorTag());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement)
|
bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement)
|
||||||
{
|
{
|
||||||
StackHeightChecker checker(m_context);
|
StackHeightChecker checker(m_context);
|
||||||
|
@ -112,6 +112,7 @@ private:
|
|||||||
virtual bool visit(Continue const& _continue) override;
|
virtual bool visit(Continue const& _continue) override;
|
||||||
virtual bool visit(Break const& _break) override;
|
virtual bool visit(Break const& _break) override;
|
||||||
virtual bool visit(Return const& _return) override;
|
virtual bool visit(Return const& _return) override;
|
||||||
|
virtual bool visit(Throw const& _throw) override;
|
||||||
virtual bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;
|
virtual bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;
|
||||||
virtual bool visit(ExpressionStatement const& _expressionStatement) override;
|
virtual bool visit(ExpressionStatement const& _expressionStatement) override;
|
||||||
virtual bool visit(PlaceholderStatement const&) override;
|
virtual bool visit(PlaceholderStatement const&) override;
|
||||||
|
@ -622,6 +622,16 @@ ASTPointer<Statement> Parser::parseStatement()
|
|||||||
statement = nodeFactory.createNode<Return>(expression);
|
statement = nodeFactory.createNode<Return>(expression);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Token::Throw:
|
||||||
|
{
|
||||||
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
ASTPointer<Expression> expression;
|
||||||
|
if (m_scanner->next() != Token::Semicolon)
|
||||||
|
BOOST_THROW_EXCEPTION(createParserError("Throw statement cannot have parameters."));
|
||||||
|
|
||||||
|
statement = nodeFactory.createNode<Throw>(/*expression*/);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Token::Identifier:
|
case Token::Identifier:
|
||||||
if (m_insideModifier && m_scanner->currentLiteral() == "_")
|
if (m_insideModifier && m_scanner->currentLiteral() == "_")
|
||||||
{
|
{
|
||||||
|
@ -171,6 +171,7 @@ namespace solidity
|
|||||||
K(Returns, "returns", 0) \
|
K(Returns, "returns", 0) \
|
||||||
K(Storage, "storage", 0) \
|
K(Storage, "storage", 0) \
|
||||||
K(Struct, "struct", 0) \
|
K(Struct, "struct", 0) \
|
||||||
|
K(Throw, "throw", 0) \
|
||||||
K(Var, "var", 0) \
|
K(Var, "var", 0) \
|
||||||
K(While, "while", 0) \
|
K(While, "while", 0) \
|
||||||
\
|
\
|
||||||
@ -316,7 +317,6 @@ namespace solidity
|
|||||||
K(Of, "of", 0) \
|
K(Of, "of", 0) \
|
||||||
K(Relocatable, "relocatable", 0) \
|
K(Relocatable, "relocatable", 0) \
|
||||||
K(Switch, "switch", 0) \
|
K(Switch, "switch", 0) \
|
||||||
K(Throw, "throw", 0) \
|
|
||||||
K(Try, "try", 0) \
|
K(Try, "try", 0) \
|
||||||
K(Type, "type", 0) \
|
K(Type, "type", 0) \
|
||||||
K(TypeOf, "typeof", 0) \
|
K(TypeOf, "typeof", 0) \
|
||||||
|
@ -34,6 +34,7 @@ ForStatement = 'for' '(' (VardefOrExprStmt)? ';' (Expression)? ';' (ExpressionSt
|
|||||||
Continue = 'continue' ';'
|
Continue = 'continue' ';'
|
||||||
Break = 'break' ';'
|
Break = 'break' ';'
|
||||||
Return = 'return' Expression? ';'
|
Return = 'return' Expression? ';'
|
||||||
|
Throw = 'throw' Expression? ';'
|
||||||
VariableDefinition = VariableDeclaration ( = Expression )? ';'
|
VariableDefinition = VariableDeclaration ( = Expression )? ';'
|
||||||
|
|
||||||
Expression = Assignment | UnaryOperation | BinaryOperation | FunctionCall | NewExpression | IndexAccess |
|
Expression = Assignment | UnaryOperation | BinaryOperation | FunctionCall | NewExpression | IndexAccess |
|
||||||
|
@ -5265,6 +5265,24 @@ BOOST_AUTO_TEST_CASE(library_stray_values)
|
|||||||
BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42)));
|
BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(simple_throw)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract Test {
|
||||||
|
function f(uint x) returns (uint) {
|
||||||
|
if (x > 10)
|
||||||
|
return x + 10;
|
||||||
|
else
|
||||||
|
throw;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode);
|
||||||
|
BOOST_CHECK(callContractFunction("f(uint256)", u256(11)) == encodeArgs(u256(21)));
|
||||||
|
BOOST_CHECK(callContractFunction("f(uint256)", u256(1)) == encodeArgs());
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user