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)));
       }

Reply via email to