Skip to content

Type Checker: skip zero-param free functions in attachedFunctions resolution#16725

Open
genisis0x wants to merge 1 commit into
argotorg:developfrom
genisis0x:fix/16610-ice-zero-param-bound-free-function
Open

Type Checker: skip zero-param free functions in attachedFunctions resolution#16725
genisis0x wants to merge 1 commit into
argotorg:developfrom
genisis0x:fix/16610-ice-zero-param-bound-free-function

Conversation

@genisis0x
Copy link
Copy Markdown

Description

Fixes #16610.

solc --bin panics with an internal compiler error when a using { zero } for T directive binds a zero-parameter free function and the call site (x.zero()) appears in the contract body before the directive:

function zero() pure returns (uint) { return 0; }

contract C {
    function f(uint z) external pure returns (uint) {
        return z.zero();
    }
    using {zero} for uint;
}
Internal compiler error:
libsolidity/ast/Types.cpp(3753): Throw in function ... withBoundFirstArgument()
Solidity assertion failed

Type::attachedFunctions() is called from member resolution while typechecking z.zero(). For library-bound entries it already filters out functions with no parameters at Types.cpp:460, but the non-library branch (free functions bound via using { zero } for T) calls addFunction() unconditionally, which asserts in FunctionType::withBoundFirstArgument(). The fatal 4731 ("does not have any parameters") in TypeChecker::endVisit(UsingForDirective) only fires later, when the directive itself is visited.

This change mirrors the existing library-binding filter for free-function bindings: empty-parameter entries are skipped during attached-function resolution. The TypeChecker still emits the 4731 error from the directive, and the call site separately emits a 9582 "member not found" error, matching the diagnostics surface that users would see for any other unattached function.

Tests

  • New test/libsolidity/syntaxTests/using/using_free_no_parameters_call_site_before_directive.sol reproduces the issue MRE and asserts both expected TypeError 9582 and TypeError 4731 instead of the prior ICE.
  • Existing using_free_no_parameters_err.sol (directive without call site) is unaffected.

Checklist

AI Disclosure

  • No AI tools were used
  • AI tools were used (details below)

…olution

When a using-for directive binds a zero-parameter free function and the
call site (`x.zero()`) appears earlier in the contract body than the
directive itself, member resolution runs before TypeChecker visits the
directive. attachedFunctions reaches addFunction(), which calls
FunctionType::withBoundFirstArgument() and asserts on
`!m_parameterTypes.empty()`, triggering an internal compiler error
before the user-visible 4731 ("function does not have any parameters")
is emitted.

Library-bound resolution already filters out zero-parameter functions in
the loop above; mirror the same filter for the non-library branch. The
TypeChecker's endVisit(UsingForDirective) still reports 4731 for the
directive itself, and the call-site separately reports 9582 ("member not
found"). The user-visible diagnostics are unchanged for well-typed code.

Fixes argotorg#16610
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ICE in FunctionType::withBoundFirstArgument when using for binds a zero-parameter function

1 participant