Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE in the codegen when using .slot on a mapping reference in assembly: InternalCompilerError: Invalid stack item name: slot #13259

Closed
emo-eth opened this issue Jul 10, 2022 · 1 comment · Fixed by #13406
Assignees
Labels
bug 🐛 should compile without error Error is reported even though it shouldn't. Source is fine.

Comments

@emo-eth
Copy link

emo-eth commented Jul 10, 2022

Description

Sometimes compiling via IR results in the following error (with Foundry):

❯ forge build
[⠆] Compiling...
[⠆] Compiling 69 files with 0.8.15
[⠔] Solc 0.8.15 finished in 3.00s
Error: 
Compiler run failed
InternalCompilerError: Invalid stack item name: slot

As the error implies, it seems to be related to storing variables that point to storage slots.

Environment

  • Compiler version: reproduced with 0.8.15,0.8.14,0.8.13
  • Framework/IDE (e.g. Truffle or Remix): Foundry
  • EVM execution environment / backend / blockchain client: Foundry
  • Operating system: macOS

Steps to Reproduce

In my case, I was able to resolve this by changing the following code from this:

        mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, tokenApprovalsPtr.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }

to this:

        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, _tokenApprovals.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }

Link to commit with issue present: https://github.com/jameswenzel/bound-layerable/blob/91b7096cfedd20bb422f5ed1f83c7e50261c2bcc/src/token/ERC721A.sol#L694
Link to commit with issue fixed: https://github.com/jameswenzel/bound-layerable/blob/770ded9df31d624f38e1db6c32d0d5c6f7e64132/src/token/ERC721A.sol#L694

While the code I changed is copied from the ERC721A repo, I'm able to build the code at that commit as-is without issues, with the IR pipeline enabled.

@cameel
Copy link
Member

cameel commented Jul 11, 2022

Thanks for the report! This indeed seems to be a bug in the compiler. I managed to create a smaller repro (see below). Simply using .slot on a storage reference to a mapping in assembly triggers it.

Looks like the bug has been there all the way since the IR was introduced (or at least the --ir option) in 0.5.8. Back then the syntax was _slot, not .slot though. Between 0.5.10 and 0.7.0 it was causing an uncaught exception in map::at() but starting with 0.7.1 it's again an ICE.

Repro

test.sol:

contract C  {
    mapping(uint => uint) private m;

    function g() public {
        mapping(uint => uint) storage mPtr = m;
        assembly {
            pop(mPtr.slot)
        }
    }
}
solc test.sol --ir
Internal compiler error:
/solidity/libsolidity/codegen/ir/IRVariable.cpp(52): Throw in function solidity::frontend::IRVariable solidity::frontend::IRVariable::part(const std::string&) const
Dynamic exception type: boost::wrapexcept<solidity::langutil::InternalCompilerError>
std::exception::what: Invalid stack item name: slot
[solidity::util::tag_comment*] = Invalid stack item name: slot

@cameel cameel changed the title Compiling via IR sometimes fails with "InternalCompilerError: Invalid stack item name: slot" ICE in the codegen when using .slot on a mapping reference in assembly InternalCompilerError: Invalid stack item name: slot Jul 11, 2022
@cameel cameel changed the title ICE in the codegen when using .slot on a mapping reference in assembly InternalCompilerError: Invalid stack item name: slot ICE in the codegen when using .slot on a mapping reference in assembly: InternalCompilerError: Invalid stack item name: slot Jul 11, 2022
@cameel cameel added bug 🐛 should compile without error Error is reported even though it shouldn't. Source is fine. labels Jul 11, 2022
@wechman wechman self-assigned this Jul 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 should compile without error Error is reported even though it shouldn't. Source is fine.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants