From: Iain Buclaw Date: Thu, 29 Jan 2026 13:06:14 +0000 (+0100) Subject: d: Fix ICE in gimplify_expr with const ref noreturn parameters [PR123046] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4ee1a549eac8d165740616376beeab73c5c6512;p=thirdparty%2Fgcc.git d: Fix ICE in gimplify_expr with const ref noreturn parameters [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)'. 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. --- 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; +}