https://gcc.gnu.org/g:ffb104a637c6ee7e70b450288a09391ee695f2d3
commit ffb104a637c6ee7e70b450288a09391ee695f2d3 Author: Mikael Morin <[email protected]> Date: Sun Aug 30 20:40:10 2026 +0200 fortran: array descriptor: Set polymorphic elem_len value [PR122521] Fortran-tested on aarch64-unknown-linux-gnu. OK for mainline? -- >8 -- Add an initialization of the array descriptor elem_len field with the size from the class descriptor, when associating a polymorphic scalar with a polymorphic assumed-rank dummy. Before this change, the array descriptor element length field was not set after the initialization of the dtype with a constructor of constant values. This means the element length was set to the only value known at compile time, the size of the declared type. This change adds an assignment setting the elem_len field after the dtype initialization, using the value from the class descriptor. The elem_len initialization is not removed from the dtype initialization, so that it is the declared type size that prevails instead of an unitialized value when the actual reference is absent, unallocated or unassociated. PR fortran/122521 gcc/fortran/ChangeLog: * trans-descriptor.cc (gfc_set_descriptor_from_scalar_class): Add an initialization of the element length with the size from the class descriptor. gcc/testsuite/ChangeLog: * gfortran.dg/sizeof_8.f90: New test. Diff: --- gcc/fortran/trans-descriptor.cc | 16 ++++++++++++++++ gcc/testsuite/gfortran.dg/sizeof_8.f90 | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index a6136b220151..0f4e973f27b4 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -976,6 +976,22 @@ gfc_set_descriptor_from_scalar_class (stmtblock_t *block, tree descr, set_descriptor_from_scalar (block, descr, TREE_TYPE (class_ref), tmp, NULL_TREE); + + /* Set the elem_len field... */ + tree vptr = gfc_class_vptr_get (class_ref); + stmtblock_t b; + gfc_init_block (&b); + gfc_conv_descriptor_elem_len_set (&b, descr, + gfc_vptr_size_get (vptr)); + tree len_init = gfc_finish_block (&b); + /* ... if the vptr is non-NULL. */ + tree vptr_non_null = fold_build2_loc (input_location, NE_EXPR, + boolean_type_node, vptr, + build_zero_cst (TREE_TYPE (vptr))); + len_init = fold_build3_loc (input_location, COND_EXPR, void_type_node, + vptr_non_null, len_init, + build_empty_stmt (input_location)); + gfc_add_expr_to_block (block, len_init); } diff --git a/gcc/testsuite/gfortran.dg/sizeof_8.f90 b/gcc/testsuite/gfortran.dg/sizeof_8.f90 new file mode 100644 index 000000000000..d0bf2cf248be --- /dev/null +++ b/gcc/testsuite/gfortran.dg/sizeof_8.f90 @@ -0,0 +1,33 @@ +! { dg-do run } +! +! Check the element length value set in a scalar descriptor associated with a +! polymorphic assumed-rank dummy. The value set in the descriptor passed to s1 +! used to be that of the declared type t1, instead of that of the effective +! type t2, causing failure in s2. + +program prog + implicit none + type :: t1 + integer :: c1 + end type + type, extends(t1) :: t2 + integer :: c2 + end type + type(t2) :: x + class(t1), allocatable :: y + x = t2(5, 13) + y = x + call s1(y, sizeof(x)) +contains + subroutine s1(a, e) + class(t1), intent(in) :: a(..) + integer(kind=8), intent(in) :: e + call s2(a, e) + end subroutine + subroutine s2(a, e) + type(*), intent(in) :: a(..) + integer(kind=8), intent(in) :: e + !print *, sizeof(a), e + if (sizeof(a) /= e) error stop 1 + end subroutine +end program
