Hi,

This patch fixes PR123046.

The ICE was caused by references to const/immutable qualified `noreturn'
declarations that were being leaked to the code generation when they
should have been omitted or replaced with `assert(0)'.

Regstrapped on x86_64-linux-gnu, committed to mainline, and backported
to releases/gcc-13, gcc-14, and gcc-15.

Regards,
Iain.

---
        PR d/123046

gcc/d/ChangeLog:

        * d-codegen.cc (build_address): Return `null' when generating the
        address of a `noreturn' declaration.
        (d_build_call): Compare TYPE_MAIN_VARIANT of type with `noreturn'.
        * decl.cc (get_fndecl_arguments): Likewise.
        * types.cc (finish_aggregate_mode): Likewise.
        (TypeVisitor::visit (TypeFunction *)): Likewise.

gcc/testsuite/ChangeLog:

        * gdc.dg/pr123046.d: New test.
---
 gcc/d/d-codegen.cc              | 14 ++++++++++++--
 gcc/d/decl.cc                   |  2 +-
 gcc/d/types.cc                  |  4 ++--
 gcc/testsuite/gdc.dg/pr123046.d | 10 ++++++++++
 4 files changed, 25 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/pr123046.d

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 9ec23546b4a..3ff3d0628ab 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -705,6 +705,11 @@ build_address (tree exp)
   if (TREE_CODE (exp) == CONST_DECL)
     exp = DECL_INITIAL (exp);
 
+  /* Type `noreturn' has no storage, return `null' for the expression.  */
+  if (DECL_P (exp) && TREE_CODE (exp) != FIELD_DECL
+      && TYPE_MAIN_VARIANT (TREE_TYPE (exp)) == noreturn_type_node)
+    return compound_expr (init, null_pointer_node);
+
   /* Some expression lowering may request an address of a compile-time 
constant,
      or other non-lvalue expression.  Make sure it is assigned to a location we
      can reference.  */
@@ -2361,7 +2366,7 @@ d_build_call (TypeFunction *tf, tree callable, tree 
object,
 
          /* Type `noreturn` is a terminator, as no other arguments can possibly
             be evaluated after it.  */
-         if (TREE_TYPE (targ) == noreturn_type_node)
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (targ)) == noreturn_type_node)
            noreturn_call = true;
 
          vec_safe_push (args, targ);
@@ -2381,7 +2386,12 @@ d_build_call (TypeFunction *tf, tree callable, tree 
object,
       unsigned int ix;
 
       FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
-       saved_args = compound_expr (saved_args, arg);
+       {
+         saved_args = compound_expr (saved_args, arg);
+
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (arg)) == noreturn_type_node)
+           break;
+       }
 
       /* Add a stub result type for the expression.  */
       tree result = build_zero_cst (TREE_TYPE (ctype));
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index b4e7fb21c22..b1f232616fc 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -184,7 +184,7 @@ get_fndecl_arguments (FuncDeclaration *decl)
 
          /* Type `noreturn` is a terminator, as no other arguments can possibly
             be evaluated after it.  */
-         if (TREE_TYPE (parm_decl) == noreturn_type_node)
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (parm_decl)) == noreturn_type_node)
            break;
 
          /* Chain them in the correct order.  */
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index e6f1bcbb904..b09c262fc86 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -963,7 +963,7 @@ public:
 
        /* Type `noreturn` is a terminator, as no other arguments can possibly
           be evaluated after it.  */
-       if (type == noreturn_type_node)
+       if (TYPE_MAIN_VARIANT (type) == noreturn_type_node)
          break;
 
        fnparams = chainon (fnparams, build_tree_list (0, type));
@@ -989,7 +989,7 @@ public:
     d_keep (t->ctype);
 
     /* Qualify function types that have the type `noreturn` as volatile.  */
-    if (fntype == noreturn_type_node)
+    if (TYPE_MAIN_VARIANT (fntype) == noreturn_type_node)
       t->ctype = build_qualified_type (t->ctype, TYPE_QUAL_VOLATILE);
 
     /* Handle any special support for calling conventions.  */
diff --git a/gcc/testsuite/gdc.dg/pr123046.d b/gcc/testsuite/gdc.dg/pr123046.d
new file mode 100644
index 00000000000..1a3cb2372cc
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr123046.d
@@ -0,0 +1,10 @@
+// { dg-do compile }
+ulong pure_hashOf(const ref typeof(*null) key)
+{
+    return hashOf(key);
+}
+
+ulong hashOf(const typeof(*null) val)
+{
+    return 0;
+}
-- 
2.43.0

Reply via email to