[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);