https://gcc.gnu.org/g:7776fe54c0897604f079d86ac3a3fc9f4fd71f27
commit 7776fe54c0897604f079d86ac3a3fc9f4fd71f27 Author: Mikael Morin <[email protected]> Date: Wed Aug 26 21:18:43 2026 +0200 fortran: array descriptor: Add a check for class container type [PR122521] Fortran-tested on aarch64-unknown-linux-gnu. OK for mainline? -- >8 -- In the function generating descriptor initialization from a scalar polymorphic reference, the data descriptor component is initialized with the _data component of the class container reference provided as input. Add a check that the input reference really has class container type before adding a subreference to the _data component. The input used to not have class container type sometimes, but as that was nowhere checked, a subcomponent reference was generated nevertheless to the first field of the polymorphic content. With polymorphic scalar coarrays, for example, the input reference matches the class->_data.data pattern, i.e. it already includes a reference to the _data field of the class container and to the data field of the array descriptor, and there is no need to add any subcomponent. The problem fixed here is less serious than it looks. A spurious reference to the first component, that has offset 0, doesn't change the resulting address. But if the type has no component at all, as in the testcase, it can cause the compilation to abort. PR fortran/122521 gcc/fortran/ChangeLog: * trans-descriptor.cc: (gfc_set_descriptor_from_scalar_class): Don't add a reference to the _data component if the base reference hasn't class container type. gcc/testsuite/ChangeLog: * gfortran.dg/assumed_rank_26.f90: New test. Diff: --- gcc/fortran/trans-descriptor.cc | 6 +++++- gcc/testsuite/gfortran.dg/assumed_rank_26.f90 | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index c7f40b46ddbd..d3304f443f6d 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -916,7 +916,11 @@ gfc_set_descriptor_from_scalar_class (stmtblock_t *block, tree descr, gfc_conv_descriptor_dtype_set (block, descr, gfc_get_dtype_rank_type (0, etype)); - tree tmp = gfc_class_data_get (scalar); + tree tmp = scalar; + if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)) + || (POINTER_TYPE_P (TREE_TYPE (tmp)) + && GFC_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (tmp))))) + tmp = gfc_class_data_get (tmp); if (!POINTER_TYPE_P (TREE_TYPE (tmp))) tmp = gfc_build_addr_expr (NULL_TREE, tmp); diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_26.f90 b/gcc/testsuite/gfortran.dg/assumed_rank_26.f90 new file mode 100644 index 000000000000..5f34c171e5b3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/assumed_rank_26.f90 @@ -0,0 +1,26 @@ +! { dg-do compile } +! { dg-additional-options "-fcoarray=single" } +! +! The following program used to cause an ICE because the initialization of the +! array descriptor for the call to `as' was generating a reference to the first +! component of `a', which has none in its declared type. + +program prog + implicit none + type :: t0 + end type + type, extends(t0) :: t1 + integer :: c1 + end type + type(t1) :: x[*] + x = t1(17) + call s(x) +contains + subroutine s(a) + class(t0), intent(in) :: a[*] + call as(a) + end subroutine + subroutine as(a) + class(t0), intent(in) :: a(..) + end subroutine +end program
