mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Bugfix and tests.
Co-authored-by: Kamil Śliwak <kamil.sliwak@codepoets.it>
This commit is contained in:
parent
d5e2925326
commit
a33da17300
@ -105,10 +105,13 @@ void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall)
|
|||||||
else
|
else
|
||||||
sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name);
|
sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name);
|
||||||
|
|
||||||
|
if (sideEffects.canTerminate)
|
||||||
|
changeUndecidedTo(State::Used, Location::Storage);
|
||||||
if (!sideEffects.canContinue)
|
if (!sideEffects.canContinue)
|
||||||
{
|
{
|
||||||
changeUndecidedTo(State::Unused, Location::Memory);
|
changeUndecidedTo(State::Unused, Location::Memory);
|
||||||
changeUndecidedTo(sideEffects.canTerminate ? State::Used : State::Unused, Location::Storage);
|
if (!sideEffects.canTerminate)
|
||||||
|
changeUndecidedTo(State::Unused, Location::Storage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
contract C {
|
||||||
|
uint public x;
|
||||||
|
function f() public {
|
||||||
|
x = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.
|
||||||
|
g();
|
||||||
|
x = 2;
|
||||||
|
}
|
||||||
|
function g() internal {
|
||||||
|
if (msg.data.length > 4) return;
|
||||||
|
assembly { return(0, 0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// f() ->
|
||||||
|
// x() -> 1
|
@ -5,7 +5,7 @@
|
|||||||
}
|
}
|
||||||
let x := 0
|
let x := 0
|
||||||
let y := 1
|
let y := 1
|
||||||
sstore(x, y)
|
sstore(x, y) // used to be removed due to the StorageWriteRemovalBeforeConditionalTermination
|
||||||
conditionallyStop()
|
conditionallyStop()
|
||||||
sstore(x, y)
|
sstore(x, y)
|
||||||
}
|
}
|
||||||
@ -16,6 +16,7 @@
|
|||||||
// {
|
// {
|
||||||
// let x := 0
|
// let x := 0
|
||||||
// let y := 1
|
// let y := 1
|
||||||
|
// sstore(x, y)
|
||||||
// conditionallyStop()
|
// conditionallyStop()
|
||||||
// sstore(x, y)
|
// sstore(x, y)
|
||||||
// }
|
// }
|
@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
function conditionallyStop() {
|
||||||
|
if calldataload(0) { leave }
|
||||||
|
return(0, 0)
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
let a := 0
|
||||||
|
let b := 1
|
||||||
|
sstore(a, b)
|
||||||
|
}
|
||||||
|
let x := 0
|
||||||
|
let y := 1
|
||||||
|
let z := 2
|
||||||
|
switch calldataload(64)
|
||||||
|
case 0 {
|
||||||
|
sstore(z, x)
|
||||||
|
g()
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
sstore(x, z) // used to be removed due to the StorageWriteRemovalBeforeConditionalTermination
|
||||||
|
}
|
||||||
|
conditionallyStop()
|
||||||
|
switch calldataload(32)
|
||||||
|
case 0 {
|
||||||
|
revert(0, 0)
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
sstore(x, z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// let x := 0
|
||||||
|
// let y := 1
|
||||||
|
// let z := 2
|
||||||
|
// switch calldataload(64)
|
||||||
|
// case 0 {
|
||||||
|
// sstore(z, x)
|
||||||
|
// g()
|
||||||
|
// }
|
||||||
|
// default { sstore(x, z) }
|
||||||
|
// conditionallyStop()
|
||||||
|
// switch calldataload(32)
|
||||||
|
// case 0 { revert(0, 0) }
|
||||||
|
// default { sstore(x, z) }
|
||||||
|
// }
|
||||||
|
// function conditionallyStop()
|
||||||
|
// {
|
||||||
|
// if calldataload(0) { leave }
|
||||||
|
// return(0, 0)
|
||||||
|
// }
|
||||||
|
// function g()
|
||||||
|
// {
|
||||||
|
// let a := 0
|
||||||
|
// sstore(a, 1)
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
function conditionallyStop() {
|
||||||
|
if calldataload(0) { leave }
|
||||||
|
return(0, 0)
|
||||||
|
}
|
||||||
|
let x := 0
|
||||||
|
let y := 1
|
||||||
|
sstore(x, y) // used to be removed due to the to the StorageWriteRemovalBeforeConditionalTermination bug
|
||||||
|
conditionallyStop()
|
||||||
|
revert(0,0)
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// let x := 0
|
||||||
|
// sstore(x, 1)
|
||||||
|
// conditionallyStop()
|
||||||
|
// revert(0, 0)
|
||||||
|
// }
|
||||||
|
// function conditionallyStop()
|
||||||
|
// {
|
||||||
|
// if calldataload(0) { leave }
|
||||||
|
// return(0, 0)
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
function conditionallyStop() {
|
||||||
|
if calldataload(0) { leave }
|
||||||
|
returnEmpty()
|
||||||
|
}
|
||||||
|
function returnEmpty() {
|
||||||
|
return(0, 0)
|
||||||
|
}
|
||||||
|
let x := 0
|
||||||
|
let y := 1
|
||||||
|
sstore(x, y) // used to be removed due to a bug
|
||||||
|
conditionallyStop()
|
||||||
|
sstore(x, y)
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// let x := 0
|
||||||
|
// let y := 1
|
||||||
|
// sstore(x, y)
|
||||||
|
// conditionallyStop()
|
||||||
|
// sstore(x, y)
|
||||||
|
// }
|
||||||
|
// function conditionallyStop()
|
||||||
|
// {
|
||||||
|
// if calldataload(0) { leave }
|
||||||
|
// returnEmpty()
|
||||||
|
// }
|
||||||
|
// function returnEmpty()
|
||||||
|
// { return(0, 0) }
|
||||||
|
// }
|
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
function neverStop() {
|
||||||
|
if calldataload(0) { leave } // prevent inlining
|
||||||
|
}
|
||||||
|
let x := 0
|
||||||
|
let y := 1
|
||||||
|
sstore(x, y) // should be removed
|
||||||
|
neverStop()
|
||||||
|
sstore(x, y)
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// step: unusedStoreEliminator
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// let x := 0
|
||||||
|
// let y := 1
|
||||||
|
// neverStop()
|
||||||
|
// sstore(x, y)
|
||||||
|
// }
|
||||||
|
// function neverStop()
|
||||||
|
// { if calldataload(0) { leave } }
|
||||||
|
// }
|
Loading…
Reference in New Issue
Block a user