https://gcc.gnu.org/g:9aa5bdf9a50fce6e3bf42f38eb9cf57abb8eecbe
commit r16-7398-g9aa5bdf9a50fce6e3bf42f38eb9cf57abb8eecbe Author: Iain Buclaw <[email protected]> Date: Sun Feb 8 20:36:11 2026 +0100 d: Fix ICE in output_constant, at varasm.cc:5662 [PR124026] PR d/124026 gcc/d/ChangeLog: * expr.cc (ExprVisitor::visit (FuncExp *)): Always convert function literal to a delegate if the expression expects one. Diff: --- gcc/d/expr.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index d05a12d5d090..8c068b083e5a 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1871,27 +1871,31 @@ public: /* Compile the declaration. */ build_lambda_tree (e->fd, e->type->toBasetype ()); - /* If nested, this will be a trampoline. */ - if (e->fd->isNested ()) - { - tree func = build_address (get_symbol_decl (e->fd)); - tree object; + tree func = build_address (get_symbol_decl (e->fd)); + Type *tb = e->type->toBasetype (); - if (this->constp_) + /* If a delegate is expected, the literal will be inferred as a delegate + even if it accesses no variables from an enclosing function. */ + if (tb->ty == TY::Tdelegate) + { + /* Static delegate variables have no context pointer. */ + if (this->constp_ || !e->fd->isNested ()) { - /* Static delegate variables have no context pointer. */ - object = null_pointer_node; - this->result_ = build_method_call (func, object, e->fd->type); + this->result_ = build_method_call (func, null_pointer_node, + e->fd->type); TREE_CONSTANT (this->result_) = 1; } else { - object = get_frame_for_symbol (e->fd); + gcc_assert (e->fd->isNested ()); + tree object = get_frame_for_symbol (e->fd); this->result_ = build_method_call (func, object, e->fd->type); } } else { + /* The function literal is a function pointer. */ + gcc_assert (tb->ty == TY::Tpointer); this->result_ = build_nop (build_ctype (e->type), build_address (get_symbol_decl (e->fd))); }
