mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6555 from sifmelcara/break-for-loop
[Yul] Disallow function definitions inside for loop init blocks
This commit is contained in:
+52
-33
@@ -126,31 +126,19 @@ Statement Parser::parseStatement()
|
||||
case Token::For:
|
||||
return parseForLoop();
|
||||
case Token::Break:
|
||||
if (m_insideForLoopBody)
|
||||
{
|
||||
auto stmt = Statement{ createWithLocation<Break>() };
|
||||
m_scanner->next();
|
||||
return stmt;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorReporter.syntaxError(location(), "Keyword break outside for-loop body is not allowed.");
|
||||
m_scanner->next();
|
||||
return {};
|
||||
}
|
||||
{
|
||||
Statement stmt{createWithLocation<Break>()};
|
||||
checkBreakContinuePosition("break");
|
||||
m_scanner->next();
|
||||
return stmt;
|
||||
}
|
||||
case Token::Continue:
|
||||
if (m_insideForLoopBody)
|
||||
{
|
||||
auto stmt = Statement{ createWithLocation<Continue>() };
|
||||
m_scanner->next();
|
||||
return stmt;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorReporter.syntaxError(location(), "Keyword continue outside for-loop body is not allowed.");
|
||||
m_scanner->next();
|
||||
return {};
|
||||
}
|
||||
{
|
||||
Statement stmt{createWithLocation<Continue>()};
|
||||
checkBreakContinuePosition("continue");
|
||||
m_scanner->next();
|
||||
return stmt;
|
||||
}
|
||||
case Token::Assign:
|
||||
{
|
||||
if (m_dialect->flavour != AsmFlavour::Loose)
|
||||
@@ -290,20 +278,24 @@ Case Parser::parseCase()
|
||||
|
||||
ForLoop Parser::parseForLoop()
|
||||
{
|
||||
bool outerForLoopBody = m_insideForLoopBody;
|
||||
m_insideForLoopBody = false;
|
||||
|
||||
RecursionGuard recursionGuard(*this);
|
||||
|
||||
ForLoopComponent outerForLoopComponent = m_currentForLoopComponent;
|
||||
|
||||
ForLoop forLoop = createWithLocation<ForLoop>();
|
||||
expectToken(Token::For);
|
||||
m_currentForLoopComponent = ForLoopComponent::ForLoopPre;
|
||||
forLoop.pre = parseBlock();
|
||||
m_currentForLoopComponent = ForLoopComponent::None;
|
||||
forLoop.condition = make_unique<Expression>(parseExpression());
|
||||
m_currentForLoopComponent = ForLoopComponent::ForLoopPost;
|
||||
forLoop.post = parseBlock();
|
||||
|
||||
m_insideForLoopBody = true;
|
||||
m_currentForLoopComponent = ForLoopComponent::ForLoopBody;
|
||||
forLoop.body = parseBlock();
|
||||
m_insideForLoopBody = outerForLoopBody;
|
||||
forLoop.location.end = forLoop.body.location.end;
|
||||
|
||||
m_currentForLoopComponent = outerForLoopComponent;
|
||||
|
||||
return forLoop;
|
||||
}
|
||||
|
||||
@@ -487,9 +479,16 @@ VariableDeclaration Parser::parseVariableDeclaration()
|
||||
FunctionDefinition Parser::parseFunctionDefinition()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
auto outerForLoopBody = m_insideForLoopBody;
|
||||
m_insideForLoopBody = false;
|
||||
ScopeGuard restoreInsideForLoopBody{[&]() { m_insideForLoopBody = outerForLoopBody; }};
|
||||
|
||||
if (m_currentForLoopComponent == ForLoopComponent::ForLoopPre)
|
||||
m_errorReporter.syntaxError(
|
||||
location(),
|
||||
"Functions cannot be defined inside a for-loop init block."
|
||||
);
|
||||
|
||||
ForLoopComponent outerForLoopComponent = m_currentForLoopComponent;
|
||||
m_currentForLoopComponent = ForLoopComponent::None;
|
||||
|
||||
FunctionDefinition funDef = createWithLocation<FunctionDefinition>();
|
||||
expectToken(Token::Function);
|
||||
funDef.name = expectAsmIdentifier();
|
||||
@@ -516,6 +515,8 @@ FunctionDefinition Parser::parseFunctionDefinition()
|
||||
}
|
||||
funDef.body = parseBlock();
|
||||
funDef.location.end = funDef.body.location.end;
|
||||
|
||||
m_currentForLoopComponent = outerForLoopComponent;
|
||||
return funDef;
|
||||
}
|
||||
|
||||
@@ -642,6 +643,24 @@ YulString Parser::expectAsmIdentifier()
|
||||
return name;
|
||||
}
|
||||
|
||||
void Parser::checkBreakContinuePosition(string const& _which)
|
||||
{
|
||||
switch (m_currentForLoopComponent)
|
||||
{
|
||||
case ForLoopComponent::None:
|
||||
m_errorReporter.syntaxError(location(), "Keyword \"" + _which + "\" needs to be inside a for-loop body.");
|
||||
break;
|
||||
case ForLoopComponent::ForLoopPre:
|
||||
m_errorReporter.syntaxError(location(), "Keyword \"" + _which + "\" in for-loop init block is not allowed.");
|
||||
break;
|
||||
case ForLoopComponent::ForLoopPost:
|
||||
m_errorReporter.syntaxError(location(), "Keyword \"" + _which + "\" in for-loop post block is not allowed.");
|
||||
break;
|
||||
case ForLoopComponent::ForLoopBody:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Parser::isValidNumberLiteral(string const& _literal)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user