Hi,

This regression in the D front-end was found to be caused by in some
cases the hidden closure parameter type being generated too early for
nested functions.  Better to update the type after the local
closure/frame type has been completed.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-m64,
committed to mainline, and backporting to releases/gcc-13.

Regards,
Iain.

---
        PR d/111650

gcc/d/ChangeLog:

        * decl.cc (get_fndecl_arguments): Move generation of frame type to ...
        (DeclVisitor::visit (FuncDeclaration *)): ... here, after the call to
        build_closure.

gcc/testsuite/ChangeLog:

        * gdc.dg/pr111650.d: New test.
---
 gcc/d/decl.cc                   | 20 ++++++++++----------
 gcc/testsuite/gdc.dg/pr111650.d | 21 +++++++++++++++++++++
 2 files changed, 31 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/pr111650.d

diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 3b7627d3dfa..0a87c85ae2e 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -163,16 +163,6 @@ get_fndecl_arguments (FuncDeclaration *decl)
          tree parm_decl = get_symbol_decl (decl->vthis);
          DECL_ARTIFICIAL (parm_decl) = 1;
          TREE_READONLY (parm_decl) = 1;
-
-         if (decl->vthis->type == Type::tvoidptr)
-           {
-             /* Replace generic pointer with back-end closure type
-                (this wins for gdb).  */
-             tree frame_type = FRAMEINFO_TYPE (get_frameinfo (decl));
-             gcc_assert (frame_type != NULL_TREE);
-             TREE_TYPE (parm_decl) = build_pointer_type (frame_type);
-           }
-
          param_list = chainon (param_list, parm_decl);
        }
 
@@ -1072,6 +1062,16 @@ public:
     /* May change cfun->static_chain.  */
     build_closure (d);
 
+    /* Replace generic pointer with back-end closure type
+       (this wins for gdb).  */
+    if (d->vthis && d->vthis->type == Type::tvoidptr)
+      {
+       tree frame_type = FRAMEINFO_TYPE (get_frameinfo (d));
+       gcc_assert (frame_type != NULL_TREE);
+       tree parm_decl = get_symbol_decl (d->vthis);
+       TREE_TYPE (parm_decl) = build_pointer_type (frame_type);
+      }
+
     if (d->vresult)
       declare_local_var (d->vresult);
 
diff --git a/gcc/testsuite/gdc.dg/pr111650.d b/gcc/testsuite/gdc.dg/pr111650.d
new file mode 100644
index 00000000000..4298a76d38f
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr111650.d
@@ -0,0 +1,21 @@
+// { dg-do compile }
+ref V require(K, V)(ref V[K] aa, K key, lazy V value);
+
+struct Root
+{
+    ulong[3] f;
+}
+
+Root[ulong] roots;
+
+Root getRoot(int fd, ulong rootID)
+{
+    return roots.require(rootID,
+    {
+            Root result;
+            inoLookup(fd, () => result);
+            return result;
+    }());
+}
+
+void inoLookup(int, scope Root delegate()) { }
-- 
2.40.1

Reply via email to