See attached patch. This fixes an ICE with %LEN of a deferred-length
character variable in ASSOCIATE.
Regression tested on x86_64.
OK for mainline?
Regards,
Jerry
---
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.
>From 6a780eef6cda472d69810104eb789e075c7186e7 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Wed, 23 Sep 2026 10:26:50 -0700
Subject: [PATCH] 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.
---
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(-)
create mode 100644 gcc/testsuite/gfortran.dg/associate_90.f90
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 4f4638f1296..c6811def4ff 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 b5eeb4cfde3..7ad9eeb2db5 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 00000000000..2190aa83693
--- /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
--
2.55.0