Dear all, after long debugging sessions, this one turned out to be a rather simple and obvious patch. The initialization block for a deferred-length character function result has to be generated even if somebody uses -fno-automatic (for whatever reason), as function results cannot be SAVEd.
Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald
From 2a57ad4fc46d6182c29137e3632a5a58496a97ba Mon Sep 17 00:00:00 2001 From: Harald Anlauf <[email protected]> Date: Tue, 24 Feb 2026 20:58:53 +0100 Subject: [PATCH] Fortran: deferred-length character results and -fno-automatic [PR78187] As the SAVE attribute cannot be specified for dummy variables and function results (F2023:C862), the option -fno-automatic should not treat them as automatically saved. PR fortran/78187 gcc/fortran/ChangeLog: * trans-decl.cc (gfc_trans_deferred_vars): An initialization block shall be generated for deferred-length character results even when -fno-automatic is given. gcc/testsuite/ChangeLog: * gfortran.dg/deferred_character_40.f90: New test. --- gcc/fortran/trans-decl.cc | 8 +- .../gfortran.dg/deferred_character_40.f90 | 81 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/deferred_character_40.f90 diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 851ccc45263..f80e7241577 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -5220,7 +5220,13 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.allocatable))) { - if (!sym->attr.save && flag_max_stack_var_size != 0) + /* Ensure that the initialization block may be generated also for + dummy and result variables when -fno-automatic is specified, which + sets flag_max_stack_var_size=0. */ + if (!sym->attr.save + && (flag_max_stack_var_size != 0 + || sym->attr.dummy + || sym->attr.result)) { tree descriptor = NULL_TREE; diff --git a/gcc/testsuite/gfortran.dg/deferred_character_40.f90 b/gcc/testsuite/gfortran.dg/deferred_character_40.f90 new file mode 100644 index 00000000000..69283441396 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/deferred_character_40.f90 @@ -0,0 +1,81 @@ +! { dg-do run } +! { dg-options "-O2 -fno-automatic" } +! +! PR fortran/78187 - deferred-length character results and -fno-automatic + +program pr78187 + implicit none + character(len=:), allocatable :: a, b, c, d + save :: b,c,d + c = scalar() + d = scalar_with_result() + if (len (c) /= 6) stop 11 + if (len (d) /= 6) stop 12 + deallocate (c,d) + c = pass_scalar() + d = pass_scalar_with_result() + if (len (c) /= 6) stop 13 + if (len (d) /= 6) stop 14 + deallocate (c,d) + call sub (c,d) + if (len (c) /= 6) stop 15 + if (len (d) /= 6) stop 16 + deallocate (c,d) + call sub2 (c,d) + if (len (c) /= 3) stop 17 + if (len (d) /= 6) stop 18 + deallocate (c,d) + a = concat ("abc","def") + b = concat ("abc","def") + if (len (a) /= 6) stop 19 + if (len (b) /= 6) stop 20 +contains + function concat(a, b) result(c) + character(len=*), intent(in) :: a, b + character(len=:), allocatable :: c + c = trim(a)//trim(b) + end function concat + + function scalar() + character(len=:), allocatable :: scalar + scalar = "abcdef" + if (len(scalar) /= 6) stop 1 + end function scalar + + function scalar_with_result() result(s) + character(len=:), allocatable :: s + s = "abcdef" + if (len(s) /= 6) stop 2 + end function scalar_with_result + + function pass_scalar () + character(len=:), allocatable :: pass_scalar + pass_scalar = scalar () + if (len(pass_scalar) /= 6) stop 3 + end function pass_scalar + + function pass_scalar_with_result() result(s) + character(len=:), allocatable :: s + s = scalar_with_result () + if (len(s) /= 6) stop 4 + end function pass_scalar_with_result + + subroutine sub (s1, s2) + character(len=:), allocatable :: s1, s2 + s1 = scalar () + s2 = scalar_with_result () + if (len(s1) /= 6) stop 5 + if (len(s2) /= 6) stop 6 + end subroutine sub + + subroutine sub2 (s1, s2) + character(len=:), allocatable :: s1, s2 + character(len=:), allocatable :: s + s = "abc" + s1 = s + s = scalar_with_result () + s2 = s + if (len(s1) /= 3) stop 7 + if (len(s2) /= 6) stop 8 + end subroutine sub2 +end program -- 2.51.0
