https://gcc.gnu.org/g:0231b076dc98eb02e3289b21ace1757782e3917b

commit r15-2131-g0231b076dc98eb02e3289b21ace1757782e3917b
Author: Andre Vehreschild <ve...@gcc.gnu.org>
Date:   Wed Jul 10 14:37:37 2024 +0200

    Fortran: Use char* for deferred length character arrays [PR82904]
    
    Randomly during compiling the pass IPA: inline would ICE.  This was
    caused by a saved deferred length string.  The length variable was not
    set, but the variable was used in the array's declaration.  Now using a
    character pointer to prevent this.
    
            PR fortran/82904
    
    gcc/fortran/ChangeLog:
    
            * trans-types.cc (gfc_sym_type): Use type `char*` for saved
            deferred length char arrays.
            * trans.cc (get_array_span): Get `.span` also for `char*` typed
            arrays, i.e. for those that have INTEGER_TYPE instead of
            ARRAY_TYPE.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/deferred_character_38.f90: New test.

Diff:
---
 gcc/fortran/trans-types.cc                          |  6 ++++--
 gcc/fortran/trans.cc                                |  4 +++-
 gcc/testsuite/gfortran.dg/deferred_character_38.f90 | 20 ++++++++++++++++++++
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index f7b80a9761c4..01ce54f0ac0a 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2334,8 +2334,10 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
          || ((sym->attr.result || sym->attr.value)
              && sym->ns->proc_name
              && sym->ns->proc_name->attr.is_bind_c)
-         || (sym->ts.deferred && (!sym->ts.u.cl
-                                  || !sym->ts.u.cl->backend_decl))
+         || (sym->ts.deferred
+             && (!sym->ts.u.cl
+                 || !sym->ts.u.cl->backend_decl
+                 || sym->attr.save))
          || (sym->attr.dummy
              && sym->attr.value
              && gfc_length_one_character_type_p (&sym->ts))))
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 1067e032621b..d4c54093cbc3 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -398,7 +398,9 @@ get_array_span (tree type, tree decl)
     return gfc_conv_descriptor_span_get (decl);
 
   /* Return the span for deferred character length array references.  */
-  if (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type))
+  if (type
+      && (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == INTEGER_TYPE)
+      && TYPE_STRING_FLAG (type))
     {
       if (TREE_CODE (decl) == PARM_DECL)
        decl = build_fold_indirect_ref_loc (input_location, decl);
diff --git a/gcc/testsuite/gfortran.dg/deferred_character_38.f90 
b/gcc/testsuite/gfortran.dg/deferred_character_38.f90
new file mode 100644
index 000000000000..d5a6c0e50136
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/deferred_character_38.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+
+! Check for PR fortran/82904
+! Contributed by G.Steinmetz  <gs...@t-online.de>
+
+! This test checks that 'IPA pass: inline' passes.
+! The initial version of the testcase contained coarrays, which does not work
+! yet.
+
+program p
+   save
+   character(:), allocatable :: x
+   character(:), allocatable :: y
+   allocate (character(3) :: y)
+   allocate (x, source='abc')
+   y = x
+
+   if (y /= 'abc') stop 1
+end
+

Reply via email to