diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 06683d8c5..414512e51 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -136,6 +136,13 @@ void ControlFlowSimplifier::operator()(Block& _block) simplify(_block.statements); } +void ControlFlowSimplifier::operator()(FunctionDefinition& _funDef) +{ + ASTModifier::operator()(_funDef); + if (!_funDef.body.statements.empty() && _funDef.body.statements.back().type() == typeid(Leave)) + _funDef.body.statements.pop_back(); +} + void ControlFlowSimplifier::visit(Statement& _st) { if (_st.type() == typeid(ForLoop)) diff --git a/libyul/optimiser/ControlFlowSimplifier.h b/libyul/optimiser/ControlFlowSimplifier.h index 1f1c287ec..c8c402c5d 100644 --- a/libyul/optimiser/ControlFlowSimplifier.h +++ b/libyul/optimiser/ControlFlowSimplifier.h @@ -34,6 +34,7 @@ struct OptimiserStepContext; * - replace switch with only default case with pop(expression) and body * - replace switch with const expr with matching case body * - replace ``for`` with terminating control flow and without other break/continue by ``if`` + * - remove ``leave`` at the end of a function. * * None of these operations depend on the data flow. The StructuralSimplifier * performs similar tasks that do depend on data flow. @@ -55,6 +56,7 @@ public: void operator()(Break&) override { ++m_numBreakStatements; } void operator()(Continue&) override { ++m_numContinueStatements; } void operator()(Block& _block) override; + void operator()(FunctionDefinition& _funDef) override; void visit(Statement& _st) override;