Hi,

This patch was committed some time ago in r14-10036, now it's being
backported to the gcc-13 and gcc-12 release branches.

The ICE 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, committed to
releases/gcc-13 and releases/gcc-12.

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.

(cherry picked from commit 4d4929fe0654d51b52a2bf6e6188d7aad0bf17ac)
---
 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 2a135b516aa..84274b3f3c3 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);
        }
 
@@ -1060,6 +1050,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.43.0

Reply via email to