FullInliner: Do not include calls whose arguments may have side-effects

This commit is contained in:
Kamil Śliwak 2023-07-11 12:33:33 +02:00
parent 5e1e0e7752
commit ba3f9dd2a2
4 changed files with 10 additions and 12 deletions

View File

@ -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:

View File

@ -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<Literal>(argument) && !holds_alternative<Identifier>(argument))
return false;
// Inline really, really tiny functions
size_t size = m_functionSizes.at(calledFunction->name);
if (size <= 1)

View File

@ -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) }

View File

@ -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)
// { }