ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
22.64k stars 5.61k forks source link

[Yul EVM code transform] Stack too deep in standalone Yul test case #15194

Open bshastry opened 2 weeks ago

bshastry commented 2 weeks ago
{
    {
        mstore(memoryguard(0x010000), 1)
        sstore(mload(calldataload(0)), 1)
        let x := foo_s()
        mstore(192, x)
        let i := 0
        for { } lt(i, 0x60) { i := add(i, 0x20) }
        {
            switch 0x7fffffffffffff
            default { break }
        }
        sstore(foo_s(), foo_s())
    }
    function foo_s() -> x
    {
        let x_1 := x
        x_1 := call(0x4000000001, callcode(0x400000001, 0x40000001, callcode(xor(0x4000001, calldatasize()), 0x400001, 0x40001, mod(0x4001, 32768), mod(0x401, 32768), mod(0x41, 32768), mod(0x5, 32768)), mod(0x7, 32768), mod(0x7f, 32768), mod(calldatasize(), 32768), mod(calldatasize(), 32768)), 0x7ff, mod(0x7fff, 32768), mod(0x7ffff, 32768), mod(0x7fffff, 32768), mod(addmod(0x7ffffff, 0x7fffffff, 0x7ffffffff), 32768))
    }
}

Repro

$ solc --strict-assembly --optimize test.yul
...
Uncaught exception:
../libyul/backends/evm/EVMObjectCompiler.cpp(106): Throw in function void solidity::yul::EVMObjectCompiler::run(solidity::yul::Object &, bool)
Dynamic exception type: boost::wrapexcept<solidity::yul::StackTooDeepError>
std::exception::what: Cannot swap Variable _1 with Slot 0x07ff: too deep in the stack by 1 slots in [ 0x7ffe 0x7fff 0x7fff 0x7fff _1 _1 _1 0x7f 0x07 0x05 0x41 0x0401 0x4001 0x040001 0x400001 _2 0x7ffe 0x7fff _1 _2 TMP[lt, 0] 0x07ff ]
memoryguard was present.
[solidity::util::tag_comment*] = Cannot swap Variable _1 with Slot 0x07ff: too deep in the stack by 1 slots in [ 0x7ffe 0x7fff 0x7fff 0x7fff _1 _1 _1 0x7f 0x07 0x05 0x41 0x0401 0x4001 0x040001 0x400001 _2 0x7ffe 0x7fff _1 _2 TMP[lt, 0] 0x07ff ]
memoryguard was present.

Commit hash: b849b327781cb71478709b28c4d0d372492cbdc1