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
