https://gcc.gnu.org/g:6c02187fb7eb8e337d4b4da2ea03d792f9d3d427
commit 6c02187fb7eb8e337d4b4da2ea03d792f9d3d427 Author: Mikael Morin <[email protected]> Date: Fri Oct 23 11:40:45 2026 +0200 fortran: Unwrap class container from descritor's element type [PR128103] TODO -- >8 -- The testcase shows one example where we use a class container type as element type of an array descriptor. This causes the element length to be initialized to the wrong value, with an effect visible by the ASSOCIATED intrinsic at execution time. This change fixes the problem by detecting the class container and unwrapping it before using it for array descriptor type creation. PR fortran/128103 gcc/fortran/ChangeLog: * trans-array.cc (gfc_conv_expr_descriptor): Unwrap any class container from the type to use as array descriptor element type. gcc/testsuite/ChangeLog: * gfortran.dg/associated_9.f90: New test. Diff: --- gcc/fortran/trans-array.cc | 8 +++++++- gcc/testsuite/gfortran.dg/associated_9.f90 | 32 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 2045424a8610..1a0415b4462c 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -8587,7 +8587,13 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) subobject for a subreference of the array. */ if (expr->ts.type == BT_CHARACTER || (subref_array_target && !se->direct_byref)) - parmtype = gfc_typenode_for_spec (&expr->ts); + { + gfc_typespec *ts = &expr->ts; + if (ts->type == BT_CLASS + && ts->u.derived->attr.is_class) + ts = &ts->u.derived->components->ts; + parmtype = gfc_typenode_for_spec (ts); + } else parmtype = gfc_get_element_type (TREE_TYPE (desc)); diff --git a/gcc/testsuite/gfortran.dg/associated_9.f90 b/gcc/testsuite/gfortran.dg/associated_9.f90 new file mode 100644 index 000000000000..06dea871a368 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associated_9.f90 @@ -0,0 +1,32 @@ +! { dg-do run } +! { dg-additional-options {-fdump-tree-original} } +! +! PR fortran/128103 +! Check the type and element length of the array descriptor for the polymorphic +! pointer X(:) used as TARGET of the ASSOCIATED intrinsic. We used to generate +! a descriptor with class container element type. +! +! There are two array descriptor variables of type T1 used as actual argument, +! one for the call to SUB, and one for the TARGET of the call to ASSOCIATED: +! { dg-final { scan-tree-dump-times {struct array01_t1 parm\.\d+;} 2 {original} } } +! Each of them initialized with an element length of 4: +! { dg-final { scan-tree-dump-times {parm\.\d+\.dtype = .\.elem_len=4} 2 {original} } } + +program prog + implicit none + integer, parameter :: n = 5 + type :: t1 + integer :: c1 + end type + type(t1), target :: a(n) + integer :: i + a = [ (t1(i*i+2), i=1,n) ] + call sub(a) +contains + subroutine sub(x) + class(t1), pointer, intent(in) :: x(:) + type(t1), pointer :: p(:) + p => a + if (.not. associated(p, x(:))) error stop 1 + end subroutine +end program
