Skip to content

Type Checker: skip zero-param bindings in operatorDefinitions matching scan#16724

Open
genisis0x wants to merge 1 commit into
argotorg:developfrom
genisis0x:fix/16613-ice-zero-param-operator-definition
Open

Type Checker: skip zero-param bindings in operatorDefinitions matching scan#16724
genisis0x wants to merge 1 commit into
argotorg:developfrom
genisis0x:fix/16613-ice-zero-param-operator-definition

Conversation

@genisis0x
Copy link
Copy Markdown

Description

Fixes #16613.

In a global using { ..., g as <op> } for T directive that mixes a valid binding (f as -, two parameters of T) with a zero-parameter binding (g as -), solc --bin panics with an internal compiler error before the user-visible 4731 (The function "g" does not have any parameters...) is emitted:

Internal compiler error:
libsolidity/ast/Types.cpp(409): Throw in function ... operatorDefinitions(...)
Solidity assertion failed

TypeChecker::endVisit(UsingForDirective) walks the bindings in order. For f it reaches the per-binding cross-scan at libsolidity/analysis/TypeChecker.cpp:4224 and calls Type::operatorDefinitions(_token, _scope, _unary). That helper iterates every binding of every using-for directive on T (including g), and asserted on !functionType->parameterTypes().empty(). The fatal 4731 for g is only fired later, when the outer loop reaches it.

This change keeps the assertion that the binding still maps to a FunctionType, but treats the empty-parameter case as a no-op for the matching scan. The TypeChecker still emits 4731 from endVisit(UsingForDirective), so the user-visible diagnostic is unchanged for the well-typed binding paths and for the standalone zero-parameter case (operator_taking_no_parameters_unary.sol is unaffected).

Tests

  • New test/libsolidity/syntaxTests/operators/userDefined/operator_zero_param_alongside_valid_binding_no_ice.sol reproduces the issue MRE (one valid - binding + one zero-parameter - binding) and asserts the expected TypeError 4731 instead of the prior ICE.

Checklist

AI Disclosure

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

…g scan

When a using-for directive contains both a valid operator binding (e.g.
`f as -`, two parameters) and a zero-parameter binding (e.g. `g as -`),
TypeChecker::endVisit(UsingForDirective) reports the per-binding fatal
error 4731 for the zero-parameter function, but only after the matching
binding has already triggered the cross-binding scan in
Type::operatorDefinitions(). That scan asserted on
`!functionType->parameterTypes().empty()` and aborted with an internal
compiler error before the user-visible 4731 was emitted.

Skip such entries explicitly inside operatorDefinitions(); the
TypeChecker still reports the visibility error from the offending binding
itself, and the matching scan no longer reaches the assertion.

Fixes argotorg#16613
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 Type::operatorDefinitions when a zero-parameter function is bound as an operator via using for

1 participant