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

commit r17-4681-ge0f62720743e7750eef0c86dfa23d5965e2de785
Author: Jerry DeLisle <[email protected]>
Date:   Wed Sep 23 10:26:50 2026 -0700

    fortran: [PR127187] ICE with %LEN of deferred-length character in ASSOCIATE
    
    A %LEN or %KIND inquiry of a deferred-length character variable gives
    an INTEGER expression that still carried the deferred flag of the
    character typespec.  An associate-name with such a selector inherited
    it, and gfc_get_symbol_decl then segfaulted looking for its string
    length.
    
    A related bug: for an associate-name whose selector is deferred-length
    character, resolve_variable reset the typespec of the expression to
    that of the associate-name unless a substring reference was present.
    An inquiry reference of the associate-name, e.g. q%len, thus reverted
    to CHARACTER, giving an ICE in conv_inquiry or a spurious error on
    comparison with an INTEGER.
    
            PR fortran/127187
    
    gcc/fortran/ChangeLog:
    
            PR fortran/127187
            * primary.cc (gfc_match_varspec): Clear the deferred flag, and
            for KIND the charlen, of the INTEGER result of a LEN or KIND
            inquiry.
            * resolve.cc (resolve_variable): Do not reset the typespec of a
            deferred-length character associate-name expression that has an
            inquiry reference.
    
    gcc/testsuite/ChangeLog:
    
            PR fortran/127187
            * gfortran.dg/associate_90.f90: New test.

Diff:
---
 gcc/fortran/primary.cc                     |  6 +++
 gcc/fortran/resolve.cc                     |  2 +-
 gcc/testsuite/gfortran.dg/associate_90.f90 | 69 ++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index f3708f125d70..ebd72e2de1fe 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -2836,6 +2836,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, 
bool sub_flag,
                  return MATCH_ERROR;
                }
              primary->ts.u.cl = NULL;
+             primary->ts.deferred = false;
              primary->ts.type = BT_INTEGER;
              primary->ts.kind = gfc_default_integer_kind;
              break;
@@ -2851,6 +2852,11 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, 
bool sub_flag,
                             "to an expression of intrinsic type");
                  return MATCH_ERROR;
                }
+             if (primary->ts.type == BT_CHARACTER)
+               {
+                 primary->ts.u.cl = NULL;
+                 primary->ts.deferred = false;
+               }
              primary->ts.type = BT_INTEGER;
              primary->ts.kind = gfc_default_integer_kind;
              break;
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 60c5610bba45..a0c7d5c5e066 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -6739,7 +6739,7 @@ resolve_variable (gfc_expr *e)
     {
       gfc_ref *ref;
       for (ref = e->ref; ref; ref = ref->next)
-       if (ref->type == REF_SUBSTRING)
+       if (ref->type == REF_SUBSTRING || ref->type == REF_INQUIRY)
          break;
       if (ref == NULL)
        e->ts = sym->ts;
diff --git a/gcc/testsuite/gfortran.dg/associate_90.f90 
b/gcc/testsuite/gfortran.dg/associate_90.f90
new file mode 100644
index 000000000000..2190aa83693a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_90.f90
@@ -0,0 +1,69 @@
+! { dg-do run }
+!
+! PR 127187
+! %LEN and %KIND inquiries of deferred-length character in ASSOCIATE.
+!
+! Contributed by Ivan Pribec
+!
+program assoc_len_kind
+  implicit none
+  character(:), allocatable :: s, a(:)
+  character(:), pointer :: p
+  character(kind=4,len=:), allocatable :: w
+  character(7) :: f = 'seven07'
+  complex :: z = (1., 2.)
+  s = 'hello'
+  a = ['ab', 'cd', 'ef']
+  w = 4_'wxyz'
+  allocate (p, source='ptr')
+
+  ! Selector contains an inquiry of a deferred-length variable
+  associate (n => s%len)
+    if (n /= 5) error stop 1
+  end associate
+  associate (n => (s%len))
+    if (n /= 5) error stop 2
+  end associate
+  associate (n => f%len)
+    if (n /= 7) error stop 3
+  end associate
+  associate (n => s%len + 0)
+    if (n /= 5) error stop 4
+  end associate
+  associate (k => z%kind)
+    if (k /= kind(z)) error stop 5
+  end associate
+  associate (k => z%kind, n => s%len)
+    if (k /= kind(z)) error stop 6
+    if (n /= 5) error stop 7
+  end associate
+  associate (n => s%len)
+    s = 'longer_string'
+    if (n /= 5) error stop 8
+  end associate
+  s = 'hello'
+  associate (n => s%kind, m => p%len, k => w%kind)
+    if (n /= 1 .or. m /= 3 .or. k /= 4) error stop 9
+  end associate
+
+  ! Inquiry of an associate-name with a deferred-length selector
+  associate (q => s)
+    if (q%len /= 5 .or. q%kind /= 1) error stop 10
+    if (q(2:3)%len /= 2) error stop 11
+    associate (n => q%len + q%kind)
+      if (n /= 6) error stop 12
+    end associate
+  end associate
+  associate (q => a)
+    if (q%len /= 2 .or. size (q) /= 3) error stop 13
+  end associate
+  associate (q => p, r => w)
+    if (q%len /= 3 .or. r%len /= 4 .or. r%kind /= 4) error stop 14
+  end associate
+  associate (q => s)
+    associate (r => q)
+      if (r%len /= 5) error stop 15
+    end associate
+  end associate
+  deallocate (p)
+end program

Reply via email to