diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index d340b5510..87976e116 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -158,6 +158,12 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) {}, move(_functionDefinition.body) }); + // Generate new names for the arguments to maintain disambiguation. + std::map newArgumentNames; + for (TypedName const& _var: stackParameters) + newArgumentNames[_var.name] = m_context.dispenser.newName(_var.name); + for (auto& parameter: _functionDefinition.parameters) + parameter.name = util::valueOrDefault(newArgumentNames, parameter.name, parameter.name); // Replace original function by a call to the new function and an assignment to the return variable from memory. _functionDefinition.body = Block{_functionDefinition.debugData, move(memoryVariableInits)}; _functionDefinition.body.statements.emplace_back(ExpressionStatement{ @@ -166,7 +172,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) _functionDefinition.debugData, Identifier{_functionDefinition.debugData, newFunctionName}, stackParameters | ranges::views::transform([&](TypedName const& _arg) { - return Expression{Identifier{_arg.debugData, _arg.name}}; + return Expression{Identifier{_arg.debugData, newArgumentNames.at(_arg.name)}}; }) | ranges::to> } }); diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul new file mode 100644 index 000000000..706a46c62 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul @@ -0,0 +1,38 @@ +{ + { + mstore(0x40, memoryguard(0x80)) + sstore(0, f(1,2,3)) + } + function f(a, b, c) -> $b1 { + if calldataload(add(sub(a,b),c)) { + $b1 := 0 + leave + } + $b1 := 1 + } + +} +// ---- +// step: fakeStackLimitEvader +// +// { +// { +// mstore(0x40, memoryguard(0xa0)) +// sstore(0, f(1, 2, 3)) +// } +// function f(a_2, b_3, c_4) -> $b1 +// { +// mstore(0x80, 0) +// f_1(a_2, b_3, c_4) +// $b1 := mload(0x80) +// } +// function f_1(a, b, c) +// { +// if calldataload(add(sub(a, b), c)) +// { +// mstore(0x80, 0) +// leave +// } +// mstore(0x80, 1) +// } +// }