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;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
* also be "var") but the actual assignment can be missing.
|
||||
|
@ -64,6 +64,7 @@ class ForStatement;
|
||||
class Continue;
|
||||
class Break;
|
||||
class Return;
|
||||
class Throw;
|
||||
class VariableDeclarationStatement;
|
||||
class ExpressionStatement;
|
||||
class Expression;
|
||||
|
@ -193,6 +193,12 @@ bool ASTJsonConverter::visit(Return const&)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTJsonConverter::visit(Throw const&)
|
||||
{
|
||||
addJsonNode("Throw", {}, true);;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTJsonConverter::visit(VariableDeclarationStatement const&)
|
||||
{
|
||||
addJsonNode("VariableDefinition", {}, true);
|
||||
@ -364,6 +370,11 @@ void ASTJsonConverter::endVisit(Return const&)
|
||||
goUp();
|
||||
}
|
||||
|
||||
void ASTJsonConverter::endVisit(Throw const&)
|
||||
{
|
||||
goUp();
|
||||
}
|
||||
|
||||
void ASTJsonConverter::endVisit(VariableDeclarationStatement const&)
|
||||
{
|
||||
goUp();
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
bool visit(Continue const& _node) override;
|
||||
bool visit(Break const& _node) override;
|
||||
bool visit(Return const& _node) override;
|
||||
bool visit(Throw const& _node) override;
|
||||
bool visit(VariableDeclarationStatement const& _node) override;
|
||||
bool visit(ExpressionStatement const& _node) override;
|
||||
bool visit(Assignment const& _node) override;
|
||||
@ -93,6 +94,7 @@ public:
|
||||
void endVisit(Continue const&) override;
|
||||
void endVisit(Break const&) override;
|
||||
void endVisit(Return const&) override;
|
||||
void endVisit(Throw const&) override;
|
||||
void endVisit(VariableDeclarationStatement const&) override;
|
||||
void endVisit(ExpressionStatement const&) override;
|
||||
void endVisit(Assignment const&) override;
|
||||
|
@ -221,6 +221,13 @@ bool ASTPrinter::visit(Return const& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Throw const& _node)
|
||||
{
|
||||
writeLine("Throw");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(VariableDeclarationStatement const& _node)
|
||||
{
|
||||
writeLine("VariableDeclarationStatement");
|
||||
@ -444,6 +451,11 @@ void ASTPrinter::endVisit(Return const&)
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Throw const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(VariableDeclarationStatement const&)
|
||||
{
|
||||
m_indentation--;
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
bool visit(Continue const& _node) override;
|
||||
bool visit(Break const& _node) override;
|
||||
bool visit(Return const& _node) override;
|
||||
bool visit(Throw const& _node) override;
|
||||
bool visit(VariableDeclarationStatement const& _node) override;
|
||||
bool visit(ExpressionStatement const& _node) override;
|
||||
bool visit(Assignment const& _node) override;
|
||||
@ -110,6 +111,7 @@ public:
|
||||
void endVisit(Continue const&) override;
|
||||
void endVisit(Break const&) override;
|
||||
void endVisit(Return const&) override;
|
||||
void endVisit(Throw const&) override;
|
||||
void endVisit(VariableDeclarationStatement const&) override;
|
||||
void endVisit(ExpressionStatement const&) override;
|
||||
void endVisit(Assignment const&) override;
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
virtual bool visit(Continue& _node) { return visitNode(_node); }
|
||||
virtual bool visit(Break& _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(ExpressionStatement& _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(Break& _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(ExpressionStatement& _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(Break 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(ExpressionStatement 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(Break 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(ExpressionStatement 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
|
@ -606,6 +606,13 @@ bool Compiler::visit(Return const& _return)
|
||||
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)
|
||||
{
|
||||
StackHeightChecker checker(m_context);
|
||||
|
@ -112,6 +112,7 @@ private:
|
||||
virtual bool visit(Continue const& _continue) override;
|
||||
virtual bool visit(Break const& _break) 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(ExpressionStatement const& _expressionStatement) override;
|
||||
virtual bool visit(PlaceholderStatement const&) override;
|
||||
|
@ -622,6 +622,16 @@ ASTPointer<Statement> Parser::parseStatement()
|
||||
statement = nodeFactory.createNode<Return>(expression);
|
||||
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:
|
||||
if (m_insideModifier && m_scanner->currentLiteral() == "_")
|
||||
{
|
||||
|
@ -171,6 +171,7 @@ namespace solidity
|
||||
K(Returns, "returns", 0) \
|
||||
K(Storage, "storage", 0) \
|
||||
K(Struct, "struct", 0) \
|
||||
K(Throw, "throw", 0) \
|
||||
K(Var, "var", 0) \
|
||||
K(While, "while", 0) \
|
||||
\
|
||||
@ -316,7 +317,6 @@ namespace solidity
|
||||
K(Of, "of", 0) \
|
||||
K(Relocatable, "relocatable", 0) \
|
||||
K(Switch, "switch", 0) \
|
||||
K(Throw, "throw", 0) \
|
||||
K(Try, "try", 0) \
|
||||
K(Type, "type", 0) \
|
||||
K(TypeOf, "typeof", 0) \
|
||||
|
@ -34,6 +34,7 @@ ForStatement = 'for' '(' (VardefOrExprStmt)? ';' (Expression)? ';' (ExpressionSt
|
||||
Continue = 'continue' ';'
|
||||
Break = 'break' ';'
|
||||
Return = 'return' Expression? ';'
|
||||
Throw = 'throw' Expression? ';'
|
||||
VariableDefinition = VariableDeclaration ( = Expression )? ';'
|
||||
|
||||
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_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()
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user