[gcc(refs/users/mikael/heads/refactor_descriptor_v206.01)] fortran: array descriptor: Unwrap class descriptor element type [PR122521]

Mikael Morin via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:c05cdf822c0899b4d3403615607336f3aaefd1e9

commit c05cdf822c0899b4d3403615607336f3aaefd1e9
Author: Mikael Morin <[email protected]>
Date:   Tue Aug 18 12:39:32 2026 +0200

    fortran: array descriptor: Unwrap class descriptor element type [PR122521]
    
    In the scalar polymorphic case, use the class descriptor data pointer type
    as element type to initialize the scalar descriptor.
    
    Before this change, it was the class descriptor type itself that was used as
    element type.  It caused the element size field to be initialized with a
    wrong value.  I couldn't find a testcase where that value had an observable
    effect though.
    
    The use of the data pointer type makes it possible to have void that comes
    out as element type.  That's what is obtained in the unlimited polymorphic
    case: the data pointer type is void*, and the pointer type is unwrapped to
    get the value type.  This causes the dtype construction to trip on an assert
    because it's not prepared for a void type, as there's no size it can guess
    from it.  This is fixed by skipping the element length initialization if the
    input type is void.
    
            PR fortran/122521
    
    gcc/fortran/ChangeLog:
    
            * trans-descriptor.cc (gfc_build_dtype_constructor): Accept NULL
            size argument.  Don't build any initialization of the elem_len field
            if size is NULL.
            (gfc_set_descriptor_from_scalar_class): Use the data pointer type as
            element type.
            * trans-types.cc (gfc_get_dtype_rank_type): Clear the size by
            default.  Don't set it if the input type is void.

Diff:
---
 gcc/fortran/trans-descriptor.cc | 22 ++++++++++++----------
 gcc/fortran/trans-types.cc      |  6 +++---
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 900d912e3a9e..857cbeafae7d 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -646,15 +646,17 @@ gfc_build_dtype_constructor (tree size, int type, int rank)
   tree field;
   vec<constructor_elt, va_gc> *v = NULL;
 
-  gcc_assert (size);
-
-  STRIP_NOPS (size);
-  size = fold_convert (size_type_node, size);
   tree dtype_type_node = get_dtype_type_node ();
-  field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
-			     GFC_DTYPE_ELEM_LEN);
-  CONSTRUCTOR_APPEND_ELT (v, field,
-			  fold_convert (TREE_TYPE (field), size));
+  if (size)
+    {
+      STRIP_NOPS (size);
+      size = fold_convert (size_type_node, size);
+      field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
+				 GFC_DTYPE_ELEM_LEN);
+      CONSTRUCTOR_APPEND_ELT (v, field,
+			      fold_convert (TREE_TYPE (field), size));
+    }
+
   field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
 			     GFC_DTYPE_VERSION);
   CONSTRUCTOR_APPEND_ELT (v, field,
@@ -910,12 +912,12 @@ void
 gfc_set_descriptor_from_scalar_class (stmtblock_t *block, tree descr,
 				      tree scalar, gfc_expr *scalar_expr)
 {
-  tree type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (scalar),
+  tree tmp = gfc_class_data_get (scalar);
+  tree type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (tmp),
 						 gfc_expr_attr (scalar_expr));
   gfc_conv_descriptor_dtype_set (block, descr,
 				 gfc_get_dtype (type));
 
-  tree tmp = gfc_class_data_get (scalar);
   if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
     tmp = gfc_build_addr_expr (NULL_TREE, tmp);
 
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 50c5f0304ddf..40348ec23546 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -1707,7 +1707,6 @@ tree
 gfc_get_dtype_rank_type (int rank, tree etype)
 {
   tree ptype;
-  tree size;
   int n;
 
   ptype = etype;
@@ -1765,6 +1764,7 @@ gfc_get_dtype_rank_type (int rank, tree etype)
       gcc_unreachable ();
     }
 
+  tree size = NULL_TREE;
   switch (n)
     {
     case BT_CHARACTER:
@@ -1772,8 +1772,8 @@ gfc_get_dtype_rank_type (int rank, tree etype)
       size = gfc_get_character_len_in_bytes (ptype);
       break;
     case BT_VOID:
-      gcc_assert (TREE_CODE (ptype) == POINTER_TYPE);
-      size = size_in_bytes (ptype);
+      if (TREE_CODE (ptype) == POINTER_TYPE)
+	size = size_in_bytes (ptype);
       break;
     default:
       size = size_in_bytes (etype);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.