Here is another small patch. Discovered while working another issue.
If I don't see a reply back, I will commit this as simple and obvious.
New test case provided.
Regression tested on x86_64.
OK for mainline?
Regards.
Jerry
---
fortran: Wrong SAME_TYPE_AS through inferred CLASS associate
name
When the selector of an associate name is a function that has not been
parsed yet, the type of the associate name is guessed and corrected
later in gfc_fixup_inferred_type_refs. For a CLASS associate name,
resolve_variable then also called gfc_fix_class_refs on references such
as
q%c1(4)%c2
where c2 is a CLASS array component. gfc_fix_class_refs added a '_data'
reference in front of the array reference that ends the chain, so the
expression was no longer polymorphic and SAME_TYPE_AS was folded to
.false. at compile time. The same reference through an associate name
whose type is known when it is parsed never goes through this call.
Skip gfc_fix_class_refs for inferred-type references, which
gfc_fixup_inferred_type_refs has already fixed up.
gcc/fortran/ChangeLog:
* resolve.cc (resolve_variable): Do not call gfc_fix_class_refs
for an inferred-type reference.
gcc/testsuite/ChangeLog:
* gfortran.dg/associate_92.f90: New test.
---From bc71a4150428796f925a7bd82ab743613076f48e Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Sat, 24 Oct 2026 09:47:44 -0400
Subject: [PATCH] fortran: Wrong SAME_TYPE_AS through inferred CLASS associate
name
When the selector of an associate name is a function that has not been
parsed yet, the type of the associate name is guessed and corrected
later in gfc_fixup_inferred_type_refs. For a CLASS associate name,
resolve_variable then also called gfc_fix_class_refs on references such
as
q%c1(4)%c2
where c2 is a CLASS array component. gfc_fix_class_refs added a '_data'
reference in front of the array reference that ends the chain, so the
expression was no longer polymorphic and SAME_TYPE_AS was folded to
.false. at compile time. The same reference through an associate name
whose type is known when it is parsed never goes through this call.
Skip gfc_fix_class_refs for inferred-type references, which
gfc_fixup_inferred_type_refs has already fixed up.
gcc/fortran/ChangeLog:
* resolve.cc (resolve_variable): Do not call gfc_fix_class_refs
for an inferred-type reference.
gcc/testsuite/ChangeLog:
* gfortran.dg/associate_92.f90: New test.
---
gcc/fortran/resolve.cc | 3 +-
gcc/testsuite/gfortran.dg/associate_92.f90 | 40 ++++++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gfortran.dg/associate_92.f90
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index ab0002a9d13..11a102098a7 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -6717,7 +6717,8 @@ resolve_variable (gfc_expr *e)
TODO Understand why class scalar expressions must be excluded. */
if (sym->assoc && !(sym->ts.type == BT_CLASS && e->rank == 0))
{
- if (sym->ts.type == BT_CLASS)
+ /* Inferred-type references are already fixed up above. */
+ if (sym->ts.type == BT_CLASS && !IS_INFERRED_TYPE (e))
gfc_fix_class_refs (e);
if (!sym->attr.dimension && !sym->attr.codimension && e->ref
&& e->ref->type == REF_ARRAY)
diff --git a/gcc/testsuite/gfortran.dg/associate_92.f90 b/gcc/testsuite/gfortran.dg/associate_92.f90
new file mode 100644
index 00000000000..7433f6794df
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_92.f90
@@ -0,0 +1,40 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! A CLASS array component referenced through an associate name whose CLASS
+! type was inferred lost its polymorphism, so SAME_TYPE_AS folded to false.
+!
+module m
+ type :: leaf_t
+ integer :: bar = 0
+ end type
+ type, extends (leaf_t) :: leaf2_t
+ integer :: baz = 7
+ end type
+ type :: mid_t
+ class(leaf_t), allocatable :: c2(:)
+ end type
+ type :: outer_t
+ class(mid_t), allocatable :: c1(:)
+ end type
+end module
+
+program p
+ use m
+ implicit none
+
+ associate (q => gfcn ())
+ if (.not. same_type_as (q%c1(4)%c2, leaf2_t ())) stop 1
+ if (same_type_as (q%c1(4)%c2, leaf_t ())) stop 2
+ if (.not. same_type_as (q%c1(4)%c2(2:3), leaf2_t ())) stop 3
+ end associate
+
+contains
+
+ function gfcn () result (y)
+ class(outer_t), allocatable :: y
+ allocate (y)
+ end function
+end program
+
+! { dg-final { scan-tree-dump-times "c2\\._vptr->_hash" 3 "original" } }
--
2.56.0