ethereum / solidity

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

False negative `Warning: Unreachable code.` in inline assembly #13670

Open leonardoalt opened 2 years ago

leonardoalt commented 2 years ago

The code in [1] issues the warning in [2], which is not true since the function is called.

[1]

contract C {
    function f(uint) external pure returns (uint) {
        assembly {
            mstore(0, id(calldataload(4)))
            return (0, 32)

            function id(x) -> y {
                y := x
            }
        }
    }
}

[2]

Warning: Unreachable code.
 --> contracts/3_Ballot.sol:7:13:
  |
7 |             function id(x) -> y {
  |             ^ (Relevant source part starts here and spans across multiple lines)
ekpyron commented 1 year ago

This should be fixed in ControlFlowBuilder (in libsolidity/analysis) - it currently doesn't properly consider control flow for assembly functions. It'd probably need a yul::Block visit, that scans for function definitions first, registering control flow nodes for them (which entails implementing the yul::FunctionDefinition visitor at least in a bogus manner at first, i.e. ignoring the flow, but adding a pseudo-node that covers the source range), and then connecting calls to user-defined yul functions to those nodes in the yul::FunctionCall visit. That way, I'd expect the regular control flow analysis to properly consider these used without any changes.

For the record: this is merely an analysis step that won't affect optimization or codegen, so it's annoying, but harmless.