https://gcc.gnu.org/g:ef03d3cfb45e0d75c137223c805ad75a3b7e319d

commit r16-8905-gef03d3cfb45e0d75c137223c805ad75a3b7e319d
Author: Harald Anlauf <[email protected]>
Date:   Thu May 7 22:34:52 2026 +0200

    Fortran: fix automatic deallocation with derived type IO [PR111952,PR125059]
    
    The implementation of derived type IO wrongly forced allocatable instances
    of the DT as static, which prevented automatic deallocation of local
    variables.  The motivation was an attempt to prevent optimizations leading
    to certain testcase failures.  Howver, the underlying reason of the problem
    was a wrong fnspec of _gfortran_transfer_derived that declared the IO
    variable as being only read ('r').  Declare the corresponding parameter as
    being written ('w').
    
            PR fortran/111952
            PR fortran/125059
    
    gcc/fortran/ChangeLog:
    
            * trans-decl.cc (gfc_finish_var_decl): Remove bogus code forcing
            a DT variable with DTIO as static.
            * trans-io.cc (gfc_build_io_library_fndecls): Fix fnspec attribute.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/dtio_37.f90: New test.
    
    (cherry picked from commit 1904b9207203bbe45d6ce6a472d6a0c7e1bbd873)

Diff:
---
 gcc/fortran/trans-decl.cc             | 10 ----------
 gcc/fortran/trans-io.cc               |  2 +-
 gcc/testsuite/gfortran.dg/dtio_37.f90 | 36 +++++++++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 4b3f75ced710..dcf4bbfdbf4f 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -756,16 +756,6 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
                && sym->attr.codimension && !sym->attr.allocatable)))
     TREE_STATIC (decl) = 1;
 
-  /* If derived-type variables with DTIO procedures are not made static
-     some bits of code referencing them get optimized away.
-     TODO Understand why this is so and fix it.  */
-  if (!sym->attr.use_assoc
-      && ((sym->ts.type == BT_DERIVED
-           && sym->ts.u.derived->attr.has_dtio_procs)
-         || (sym->ts.type == BT_CLASS
-             && CLASS_DATA (sym)->ts.u.derived->attr.has_dtio_procs)))
-    TREE_STATIC (decl) = 1;
-
   /* Treat asynchronous variables the same as volatile, for now.  */
   if (sym->attr.volatile_ || sym->attr.asynchronous)
     {
diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc
index a18b2bca6aa6..046fb57bcd0e 100644
--- a/gcc/fortran/trans-io.cc
+++ b/gcc/fortran/trans-io.cc
@@ -416,7 +416,7 @@ gfc_build_io_library_fndecls (void)
        integer_type_node, gfc_charlen_type_node);
 
   iocall[IOCALL_X_DERIVED] = gfc_build_library_function_decl_with_spec (
-       get_identifier (PREFIX("transfer_derived")), ". w r ",
+       get_identifier (PREFIX("transfer_derived")), ". w w ",
        void_type_node, 2, dt_parm_type, pvoid_type_node);
 
   /* Library entry points */
diff --git a/gcc/testsuite/gfortran.dg/dtio_37.f90 
b/gcc/testsuite/gfortran.dg/dtio_37.f90
new file mode 100644
index 000000000000..021d0e180b2a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dtio_37.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! { dg-additional-options "-O2" }
+!
+! PR fortran/125059 - derived type IO and automatic deallocation
+! PR fortran/111952
+
+module m
+  type t
+     integer :: i = 42
+   contains
+     procedure :: w
+     generic :: write(formatted) => w
+  end type t
+contains
+  subroutine w(dtv,unit,iotype,v_list,iostat,iomsg)
+    class(t),        intent(in)    :: dtv
+    integer,         intent(in)    :: unit
+    character(len=*),intent(in)    :: iotype
+    integer,         intent(in)    :: v_list(:)
+    integer,         intent(out)   :: iostat
+    character(len=*),intent(inout) :: iomsg
+    write(unit,*,iostat=iostat,iomsg=iomsg) dtv%i
+  end subroutine w
+end
+
+program p
+  use m
+  call f()
+  call f()
+contains
+  subroutine f()
+    type(t), allocatable :: a(:)
+    allocate (a(1))
+    print *, a(1)
+  end subroutine f
+end

Reply via email to