Simplified version of the patch.

On Sat, 20 Dec 2025 17:10:30 +0100
Christopher Albert <[email protected]> wrote:

> Implements Fortran 2003 4.5.5.2 finalization rule: function results
> are finalized after execution of the innermost executable construct.
> Fixes constructor/finalizer ICE for non-allocatable types. PR 121472
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121472
>From 334a57da9d6e6965c71bcef5467ce2c3aaffb756 Mon Sep 17 00:00:00 2001
From: Christopher Albert <[email protected]>
Date: Sat, 20 Dec 2025 21:22:18 +0100
Subject: [PATCH] fortran: Fix ICE with constructor for finalized zero-size
 type [PR121472]

When a derived type has a final subroutine and a constructor interface,
but is effectively zero-sized, the gimplifier fails on the finalization
code.  The existing check for empty types (!derived->components) only
catches completely empty types, not types with empty components.
Replace with a tree-level TYPE_SIZE_UNIT check that catches all
zero-size cases.

	PR fortran/121472

gcc/fortran/ChangeLog:

	* trans.cc (gfc_finalize_tree_expr): Replace !derived->components
	check with TYPE_SIZE_UNIT check for zero-size types.

gcc/testsuite/ChangeLog:

	* gfortran.dg/pr121472.f90: New test.

Signed-off-by: Christopher Albert <[email protected]>
---
 gcc/fortran/trans.cc                   |  7 ++++--
 gcc/testsuite/gfortran.dg/pr121472.f90 | 33 ++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pr121472.f90

diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 47396c3cbab..ba579894bbc 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -1638,12 +1638,15 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
     }
   else if (derived && gfc_is_finalizable (derived, NULL))
     {
-      if (!derived->components && (!rank || attr.elemental))
+      tree type = TREE_TYPE (se->expr);
+      if (type && TYPE_SIZE_UNIT (type)
+	  && integer_zerop (TYPE_SIZE_UNIT (type))
+	  && (!rank || attr.elemental))
 	{
 	  /* Any attempt to assign zero length entities, causes the gimplifier
 	     all manner of problems. Instead, a variable is created to act as
 	     as the argument for the final call.  */
-	  desc = gfc_create_var (TREE_TYPE (se->expr), "zero");
+	  desc = gfc_create_var (type, "zero");
 	}
       else if (se->direct_byref)
 	{
diff --git a/gcc/testsuite/gfortran.dg/pr121472.f90 b/gcc/testsuite/gfortran.dg/pr121472.f90
new file mode 100644
index 00000000000..00c990cd267
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr121472.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! PR fortran/121472 - ICE with constructor for finalized zero-size type
+
+module pr121472_m
+    implicit none
+    type r
+    end type
+
+    type ip
+        type(r) :: r_member
+    contains
+        final :: ipd
+    end type
+
+    interface ip
+        module procedure ipc
+    end interface
+contains
+    subroutine ipd(this)
+        type(ip), intent(inout) :: this
+    end subroutine
+
+    function ipc() result(res)
+        type(ip) :: res
+    end function
+end module
+
+program test
+    use pr121472_m
+    implicit none
+    type(ip) :: p
+    p = ip()
+end program
-- 
2.52.0

Reply via email to