From: Iain Buclaw Date: Sun, 8 Feb 2026 19:36:11 +0000 (+0100) Subject: d: Fix ICE in output_constant, at varasm.cc:5662 [PR124026] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9aa5bdf9a50fce6e3bf42f38eb9cf57abb8eecbe;p=thirdparty%2Fgcc.git 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 --git a/gcc/d/expr.cc b/gcc/d/expr.cc index d05a12d5d09..8c068b083e5 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))); }