https://gcc.gnu.org/g:2acc6fd276b48579f712d1016519c0b2382a6aa6
commit r15-11177-g2acc6fd276b48579f712d1016519c0b2382a6aa6 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 24c9e2072170..f63845b1f419 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -745,16 +745,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 ccbc47147538..d5c1d7fa526b 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
