https://gcc.gnu.org/g:08aca07552f8c3be0649ad1f56ea6124c09237c4
commit 08aca07552f8c3be0649ad1f56ea6124c09237c4 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Tue Jul 15 20:30:45 2025 +0200 Extraction gfc_build_default_class_descriptor Correction régression class_allocate_14 Diff: --- gcc/fortran/trans-decl.cc | 24 ++-------------------- gcc/fortran/trans-descriptor.cc | 44 ++++++++++++++++++++++++++++++++++++----- gcc/fortran/trans-descriptor.h | 4 +++- gcc/fortran/trans-expr.cc | 14 ++++++++++--- gcc/fortran/trans.h | 1 + 5 files changed, 56 insertions(+), 31 deletions(-) diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 66fd67e61f60..65a782b6dddf 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -4926,30 +4926,10 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) && (sym->attr.save || flag_max_stack_var_size == 0) && CLASS_DATA (sym)->attr.allocatable) { - tree vptr; - - if (UNLIMITED_POLY (sym)) - vptr = null_pointer_node; - else - { - gfc_symbol *vsym; - vsym = gfc_find_derived_vtab (sym->ts.u.derived); - vptr = gfc_get_symbol_decl (vsym); - vptr = gfc_build_addr_expr (NULL, vptr); - } - - if (CLASS_DATA (sym)->attr.dimension - || (CLASS_DATA (sym)->attr.codimension - && flag_coarray != GFC_FCOARRAY_LIB)) - { - tmp = gfc_class_data_get (sym->backend_decl); - tmp = gfc_build_null_descriptor (TREE_TYPE (tmp)); - } - else - tmp = null_pointer_node; + tree class_type = TREE_TYPE (sym->backend_decl); DECL_INITIAL (sym->backend_decl) - = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp); + = gfc_build_default_class_descriptor (sym->ts, class_type); TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1; } else if ((sym->attr.dimension || sym->attr.codimension diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 27c85d4e73c1..57570145118d 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -173,8 +173,8 @@ gfc_get_cfi_dim_sm (tree desc, tree idx) #define UBOUND_SUBFIELD 2 -static tree -get_type_field (tree type, unsigned field_idx, tree field_type = NULL_TREE) +tree +gfc_get_type_field (tree type, unsigned field_idx, tree field_type = NULL_TREE) { tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx); gcc_assert (field != NULL_TREE @@ -187,7 +187,7 @@ get_type_field (tree type, unsigned field_idx, tree field_type = NULL_TREE) static tree get_ref_comp (tree ref, unsigned field_idx, tree type = NULL_TREE) { - tree field = get_type_field (TREE_TYPE (ref), field_idx, type); + tree field = gfc_get_type_field (TREE_TYPE (ref), field_idx, type); return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), ref, field, NULL_TREE); @@ -415,8 +415,9 @@ gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, int value) tree type = TREE_TYPE (desc); gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); - tree dtype_field = get_type_field (type, DTYPE_FIELD, get_dtype_type_node ()); - tree field = get_type_field (TREE_TYPE (dtype_field), GFC_DTYPE_TYPE); + tree dtype_field = gfc_get_type_field (type, DTYPE_FIELD, + get_dtype_type_node ()); + tree field = gfc_get_type_field (TREE_TYPE (dtype_field), GFC_DTYPE_TYPE); tree type_value = build_int_cst (TREE_TYPE (field), value); gfc_conv_descriptor_type_set (block, desc, type_value); @@ -706,3 +707,36 @@ gfc_init_descriptor_result (stmtblock_t *block, tree descr) gfc_conv_descriptor_data_set (block, descr, null_pointer_node); } + +tree +gfc_build_default_class_descriptor (const gfc_typespec &ts, tree class_type) +{ + gcc_assert (ts.type == BT_CLASS); + + gfc_symbol *derived = ts.u.derived; + + tree vptr; + if (derived->attr.unlimited_polymorphic) + vptr = null_pointer_node; + else + { + gfc_symbol *vsym; + vsym = gfc_find_derived_vtab (derived); + vptr = gfc_get_symbol_decl (vsym); + vptr = gfc_build_addr_expr (NULL, vptr); + } + + tree tmp; + if (derived->components->attr.dimension + || (derived->components->attr.codimension + && flag_coarray != GFC_FCOARRAY_LIB)) + { + tmp = gfc_class_type_data_field_get (class_type); + tmp = gfc_build_null_descriptor (TREE_TYPE (tmp)); + } + else + tmp = null_pointer_node; + + return gfc_class_set_static_fields (class_type, vptr, tmp); +} + diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 0b6540116452..f5b5e59f1cfe 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see /* Build a null array descriptor constructor. */ tree gfc_build_null_descriptor (tree); -tree gfc_build_default_class_descriptor (tree, gfc_typespec &); +tree gfc_build_default_class_descriptor (const gfc_typespec &, tree); void gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *, tree); void gfc_set_scalar_null_descriptor (stmtblock_t *block, tree, gfc_symbol *, gfc_expr *, tree); void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree, @@ -46,6 +46,8 @@ tree gfc_get_cfi_dim_extent (tree desc, tree idx); tree gfc_get_cfi_dim_sm (tree desc, tree idx); +tree gfc_get_type_field (tree, unsigned, tree); + tree gfc_get_descriptor_dimension (tree desc); tree gfc_conv_descriptor_token (tree desc); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index e34716a99ad8..39e953fa2af3 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -223,20 +223,28 @@ gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr) tree -gfc_class_set_static_fields (tree decl, tree vptr, tree data) +gfc_class_type_data_field_get (tree class_type) +{ + return gfc_advance_chain (TYPE_FIELDS (class_type), + CLASS_DATA_FIELD); +} + + +tree +gfc_class_set_static_fields (tree decl_type, tree vptr, tree data) { tree tmp; tree field; vec<constructor_elt, va_gc> *init = NULL; - field = TYPE_FIELDS (TREE_TYPE (decl)); + field = TYPE_FIELDS (decl_type); tmp = gfc_advance_chain (field, CLASS_DATA_FIELD); CONSTRUCTOR_APPEND_ELT (init, tmp, data); tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD); CONSTRUCTOR_APPEND_ELT (init, tmp, vptr); - return build_constructor (TREE_TYPE (decl), init); + return build_constructor (decl_type, init); } diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 461b0cdac71c..798bf0e8a0dc 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -430,6 +430,7 @@ typedef struct gfc_wrapped_block; /* Class API functions. */ +tree gfc_class_type_data_field_get (tree); tree gfc_class_set_static_fields (tree, tree, tree); tree gfc_class_data_get (tree); tree gfc_class_vptr_get (tree);