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

Reply via email to