https://gcc.gnu.org/g:18b2b8c0b2745df0ad297753fa3fc3a8083543b8

commit r17-5067-g18b2b8c0b2745df0ad297753fa3fc3a8083543b8
Author: Jerry DeLisle <[email protected]>
Date:   Thu Jun 11 17:35:00 2026 -0700

    fortran: [PR125760] Fix ICE in SELECT TYPE with array-section selector of a 
class array
    
    In trans_associate_var, get the class container for the _len copy
    from the selector expression when target_expr is not a _data
    COMPONENT_REF.
    
    Assisted-by: Claude Opus 5.5
    
            PR fortran/125760
    
    gcc/fortran/ChangeLog:
    
            * trans-stmt.cc (trans_associate_var): Use
            gfc_get_class_from_gfc_expr when target_expr is not a
            COMPONENT_REF.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/select_type_52.f90: New test.

Diff:
---
 gcc/fortran/trans-stmt.cc                    |  6 ++-
 gcc/testsuite/gfortran.dg/select_type_52.f90 | 55 ++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 2a87176ffa9f..b1bd044ff058 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -2273,9 +2273,13 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block 
*block)
                   descriptor to get the target_expr.  */
                target_expr =
                    GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
-             else
+             else if (TREE_CODE (target_expr) == COMPONENT_REF)
                /* Strip the _data component from the target_expr.  */
                target_expr = TREE_OPERAND (target_expr, 0);
+             else
+               /* An array section selector yields a bare descriptor; get the
+                  class container from the selector expression.  */
+               target_expr = gfc_get_class_from_gfc_expr (e);
              /* Add a reference to the _len comp to the target expr.  */
              tmp = gfc_class_len_get (target_expr);
              /* Get the component-ref for the temp structure's _len comp.  */
diff --git a/gcc/testsuite/gfortran.dg/select_type_52.f90 
b/gcc/testsuite/gfortran.dg/select_type_52.f90
new file mode 100644
index 000000000000..b3eaa2b61524
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/select_type_52.f90
@@ -0,0 +1,55 @@
+! { dg-do run }
+!
+! PR 125760
+!
+! SELECT TYPE whose selector is an array section of an unlimited-polymorphic
+! array used to ICE in trans_associate_var (tree_operand_check at
+! trans-stmt.cc): the section yields a bare descriptor with no link back to the
+! class container, so stripping the _data component reference failed.
+
+program p
+  type t
+     integer :: i
+  end type t
+
+  ! Pointer to a class array.
+  class(*), pointer :: ptr(:)
+  integer, target :: arr(5) = [1, 2, 3, 4, 5]
+
+  ! Allocatable class array.
+  class(*), allocatable :: alo(:)
+
+  ! Class allocatable array component.
+  type cc
+     class(*), allocatable :: cmp(:)
+  end type cc
+  type(cc) :: obj
+
+  ptr => arr
+  select type (a => ptr(2:4))
+   type is (integer)
+     if (any (a /= [2, 3, 4])) stop 1
+  class default
+     stop 2
+  end select
+
+  ! Strided section.
+  select type (a => ptr(1:5:2))
+   type is (integer)
+     if (any (a /= [1, 3, 5])) stop 3
+  end select
+
+  allocate (alo, source = [t(10), t(20), t(30), t(40)])
+  select type (a => alo(2:3))
+   type is (t)
+     if (a(1)%i /= 20 .or. a(2)%i /= 30) stop 4
+  class default
+     stop 5
+  end select
+
+  allocate (obj%cmp, source = [11, 22, 33])
+  select type (a => obj%cmp(2:3))
+   type is (integer)
+     if (any (a /= [22, 33])) stop 6
+  end select
+end program p

Reply via email to