mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simplify single-run for loops to if statements.
This commit is contained in:
@@ -115,9 +115,51 @@ void ControlFlowSimplifier::operator()(Block& _block)
|
||||
simplify(_block.statements);
|
||||
}
|
||||
|
||||
void ControlFlowSimplifier::visit(Statement& _st)
|
||||
{
|
||||
if (_st.type() == typeid(ForLoop))
|
||||
{
|
||||
ForLoop& forLoop = boost::get<ForLoop>(_st);
|
||||
yulAssert(forLoop.pre.statements.empty(), "");
|
||||
|
||||
size_t outerBreak = m_numBreakStatements;
|
||||
size_t outerContinue = m_numContinueStatements;
|
||||
m_numBreakStatements = 0;
|
||||
m_numContinueStatements = 0;
|
||||
|
||||
ASTModifier::visit(_st);
|
||||
|
||||
if (!forLoop.body.statements.empty())
|
||||
{
|
||||
bool isTerminating = false;
|
||||
TerminationFinder::ControlFlow controlFlow = TerminationFinder::controlFlowKind(forLoop.body.statements.back());
|
||||
if (controlFlow == TerminationFinder::ControlFlow::Break)
|
||||
{
|
||||
isTerminating = true;
|
||||
--m_numBreakStatements;
|
||||
}
|
||||
else if (controlFlow == TerminationFinder::ControlFlow::Terminate)
|
||||
isTerminating = true;
|
||||
|
||||
if (isTerminating && m_numContinueStatements == 0 && m_numBreakStatements == 0)
|
||||
{
|
||||
If replacement{forLoop.location, std::move(forLoop.condition), std::move(forLoop.body)};
|
||||
if (controlFlow == TerminationFinder::ControlFlow::Break)
|
||||
replacement.body.statements.resize(replacement.body.statements.size() - 1);
|
||||
_st = std::move(replacement);
|
||||
}
|
||||
}
|
||||
|
||||
m_numBreakStatements = outerBreak;
|
||||
m_numContinueStatements = outerContinue;
|
||||
}
|
||||
else
|
||||
ASTModifier::visit(_st);
|
||||
}
|
||||
|
||||
void ControlFlowSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
||||
{
|
||||
GenericFallbackReturnsVisitor<OptionalStatements, If, Switch, ForLoop> const visitor(
|
||||
GenericFallbackReturnsVisitor<OptionalStatements, If, Switch> const visitor(
|
||||
[&](If& _ifStmt) -> OptionalStatements {
|
||||
if (_ifStmt.body.statements.empty())
|
||||
{
|
||||
@@ -136,9 +178,6 @@ void ControlFlowSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
||||
else if (_switchStmt.cases.size() == 1)
|
||||
return reduceSingleCaseSwitch(_switchStmt);
|
||||
|
||||
return {};
|
||||
},
|
||||
[&](ForLoop&) -> OptionalStatements {
|
||||
return {};
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user