]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Fix ICE in output_constant, at varasm.cc:5662 [PR124026]
authorIain Buclaw <ibuclaw@gdcproject.org>
Sun, 8 Feb 2026 19:36:11 +0000 (20:36 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sun, 8 Feb 2026 19:55:39 +0000 (20:55 +0100)
PR d/124026

gcc/d/ChangeLog:

* expr.cc (ExprVisitor::visit (FuncExp *)): Always convert function
literal to a delegate if the expression expects one.

gcc/d/expr.cc

index d05a12d5d090cfdb4b6bd3140006369347797dcd..8c068b083e5aeac9cf1ed1a42e9e5622439fb8f4 100644 (file)
@@ -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)));
       }