https://gcc.gnu.org/g:feb0ebab3becfb28161e897c8fdf03c33593821e
commit feb0ebab3becfb28161e897c8fdf03c33593821e 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 abc606dc627f..153196e6c683 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
