diff --git a/Changelog.md b/Changelog.md index 4da52893a..fa2ea9666 100644 --- a/Changelog.md +++ b/Changelog.md @@ -30,6 +30,7 @@ Bugfixes: * SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter. * Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors. * Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation. + * Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form. * Yul Optimizer: Fix optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation. AST Changes: diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 16bfcf125..ebf82e763 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -189,6 +189,12 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite) if (m_noInlineFunctions.count(_funCall.functionName.name) || recursive(*calledFunction)) return false; + // No inlining of calls where argument expressions may have side-effects. + // To avoid running into this, make sure that ExpressionSplitter runs before FullInliner. + for (auto const& argument: _funCall.arguments) + if (!holds_alternative(argument) && !holds_alternative(argument)) + return false; + // Inline really, really tiny functions size_t size = m_functionSizes.at(calledFunction->name); if (size <= 1) diff --git a/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_with_side_effects.yul b/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_with_side_effects.yul index 3a297b9d5..a89dd8913 100644 --- a/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_with_side_effects.yul +++ b/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_with_side_effects.yul @@ -11,12 +11,7 @@ // // { // { -// let ret_3 := 0 -// revert(0, 0) -// let b_1 := ret_3 -// let ret_1_4 := 0 -// return(0, 0) -// let a_2 := ret_1_4 +// empty(fun_return(), fun_revert()) // } // function fun_revert() -> ret // { revert(0, 0) } diff --git a/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_without_side_effects.yul b/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_without_side_effects.yul index d3516f66c..8f903b484 100644 --- a/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_without_side_effects.yul +++ b/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/call_arguments_without_side_effects.yul @@ -31,13 +31,9 @@ // let c_4 := z // let b_5 := y // let a_6 := x -// let c_7 := calldataload(333) -// let b_8 := sload(222) -// let a_9 := mload(111) +// empty(mload(111), sload(222), calldataload(333)) // let a_1 := 222 -// let c_10 := mload(333) -// let b_11 := a_1 -// let a_12 := 111 +// empty(111, a_1, mload(333)) // } // function empty(a, b, c) // { }