mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Do not remove potentially reverting returndatacopy cases.
This commit is contained in:
parent
30335c13ff
commit
9fa907aac2
@ -9,6 +9,7 @@ Compiler Features:
|
|||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* ABI Encoder: When encoding an empty string coming from storage do not add a superfluous empty slot for data.
|
* ABI Encoder: When encoding an empty string coming from storage do not add a superfluous empty slot for data.
|
||||||
|
* Yul Optimizer: Do not remove ``returndatacopy`` in cases in which it might perform out-of-bounds reads that unconditionally revert as out-of-gas. Previously, any ``returndatacopy`` that wrote to memory that was never read from was removed without accounting for the out-of-bounds condition.
|
||||||
|
|
||||||
|
|
||||||
### 0.8.14 (2022-05-17)
|
### 0.8.14 (2022-05-17)
|
||||||
|
@ -157,7 +157,25 @@ void UnusedStoreEliminator::visit(Statement const& _statement)
|
|||||||
yulAssert(isCandidateForRemoval == (isStorageWrite || (!m_ignoreMemory && isMemoryWrite)));
|
yulAssert(isCandidateForRemoval == (isStorageWrite || (!m_ignoreMemory && isMemoryWrite)));
|
||||||
if (isCandidateForRemoval)
|
if (isCandidateForRemoval)
|
||||||
{
|
{
|
||||||
m_stores[YulString{}].insert({&_statement, State::Undecided});
|
State initialState = State::Undecided;
|
||||||
|
if (*instruction == Instruction::RETURNDATACOPY)
|
||||||
|
{
|
||||||
|
initialState = State::Used;
|
||||||
|
auto startOffset = identifierNameIfSSA(funCall->arguments.at(1));
|
||||||
|
auto length = identifierNameIfSSA(funCall->arguments.at(2));
|
||||||
|
KnowledgeBase knowledge(m_dialect, [this](YulString _var) { return util::valueOrNullptr(m_ssaValues, _var); });
|
||||||
|
if (length && startOffset)
|
||||||
|
{
|
||||||
|
FunctionCall const* lengthCall = get_if<FunctionCall>(m_ssaValues.at(*length).value);
|
||||||
|
if (
|
||||||
|
knowledge.knownToBeZero(*startOffset) &&
|
||||||
|
lengthCall &&
|
||||||
|
toEVMInstruction(m_dialect, lengthCall->functionName.name) == Instruction::RETURNDATASIZE
|
||||||
|
)
|
||||||
|
initialState = State::Undecided;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_stores[YulString{}].insert({&_statement, initialState});
|
||||||
vector<Operation> operations = operationsFromFunctionCall(*funCall);
|
vector<Operation> operations = operationsFromFunctionCall(*funCall);
|
||||||
yulAssert(operations.size() == 1, "");
|
yulAssert(operations.size() == 1, "");
|
||||||
m_storeOperations[&_statement] = move(operations.front());
|
m_storeOperations[&_statement] = move(operations.front());
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
returndatacopy(0,0,32)
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >homestead
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// { { returndatacopy(0, 0, 32) } }
|
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
returndatacopy(0,0,returndatasize())
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >homestead
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// let _1 := returndatasize()
|
||||||
|
// let _2 := 0
|
||||||
|
// let _3 := 0
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
returndatacopy(0,1,returndatasize())
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >homestead
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// returndatacopy(0, 1, returndatasize())
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
let s := returndatasize()
|
||||||
|
returndatacopy(0,0,s)
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >homestead
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// let s := returndatasize()
|
||||||
|
// let _1 := 0
|
||||||
|
// let _2 := 0
|
||||||
|
// }
|
||||||
|
// }
|
Loading…
Reference in New Issue
Block a user