https://gcc.gnu.org/g:e3de44455296f04e014dad8c9efaef858384cfac
commit e3de44455296f04e014dad8c9efaef858384cfac Author: Mikael Morin <mik...@gcc.gnu.org> Date: Sat Dec 7 22:22:10 2024 +0100 Sauvegarde modifs Annulation suppression else Correction assertions Initialisation vptr Non initialisation elem_len pour les conteneurs de classe Mise à jour class_allocatable_14 Diff: --- gcc/fortran/trans-array.cc | 52 ++++++++++++++++++++++ gcc/fortran/trans-array.h | 2 + gcc/fortran/trans-decl.cc | 58 +++++-------------------- gcc/testsuite/gfortran.dg/class_allocate_14.f90 | 2 +- 4 files changed, 66 insertions(+), 48 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 268de211cd66..d15576adde10 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -734,6 +734,58 @@ gfc_build_null_descriptor (tree type, gfc_typespec &ts, } +tree +gfc_build_default_class_descriptor (tree type, gfc_typespec &ts) +{ + vec<constructor_elt, va_gc> *v = nullptr; + + tree fields = TYPE_FIELDS (type); + +#define CLASS_DATA_FIELD 0 +#define CLASS_VPTR_FIELD 1 + + tree data_field = gfc_advance_chain (fields, CLASS_DATA_FIELD); + tree data_type = TREE_TYPE (data_field); + + gcc_assert (ts.type == BT_CLASS); + tree data_value; + if (ts.u.derived->components->attr.dimension + || (ts.u.derived->components->attr.codimension + && flag_coarray != GFC_FCOARRAY_LIB)) + { + gcc_assert (GFC_DESCRIPTOR_TYPE_P (data_type)); + data_value = gfc_build_null_descriptor (data_type, + ts, + ts.u.derived->components->as->rank, + ts.u.derived->components->attr); + } + else + { + gcc_assert (POINTER_TYPE_P (data_type)); + data_value = fold_convert (data_type, null_pointer_node); + } + CONSTRUCTOR_APPEND_ELT (v, data_field, data_value); + + tree vptr_field = gfc_advance_chain (fields, CLASS_VPTR_FIELD); + + tree vptr_value; + if (ts.u.derived->attr.unlimited_polymorphic) + vptr_value = fold_convert (TREE_TYPE (vptr_field), null_pointer_node); + else + { + gfc_symbol *vsym = gfc_find_derived_vtab (ts.u.derived); + tree vsym_decl = gfc_get_symbol_decl (vsym); + vptr_value = gfc_build_addr_expr (nullptr, vsym_decl); + } + CONSTRUCTOR_APPEND_ELT (v, vptr_field, vptr_value); + +#undef CLASS_DATA_FIELD +#undef CLASS_VPTR_FIELD + + return build_constructor (type, v); +} + + void gfc_clear_descriptor (gfc_expr *var_ref, gfc_se &var) { diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 1bb3294b0749..63a77d562a7b 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -140,6 +140,8 @@ void gfc_set_delta (gfc_loopinfo *); void gfc_conv_resolve_dependencies (gfc_loopinfo *, gfc_ss *, gfc_ss *); /* Build a null array descriptor constructor. */ tree gfc_build_null_descriptor (tree); +tree gfc_build_default_class_descriptor (tree, gfc_typespec &); +void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *sym, tree descriptor); /* Get a single array element. */ void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *); diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 4ae22a5584d0..dad15858fa6a 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -4780,16 +4780,14 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym)) { /* Nullify explicit return class arrays on entry. */ - tree type; tmp = get_proc_result (proc_sym); - if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) - { - gfc_start_block (&init); - tmp = gfc_class_data_get (tmp); - type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp)); - gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0)); - gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE); - } + if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) + { + gfc_start_block (&init); + tmp = gfc_class_data_get (tmp); + gfc_clear_descriptor (&init, proc_sym, tmp); + gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE); + } } @@ -4931,48 +4929,13 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) } } - if (sym->attr.pointer && sym->attr.dimension - && sym->attr.save == SAVE_NONE - && !sym->attr.use_assoc - && !sym->attr.host_assoc - && !sym->attr.dummy - && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl))) - { - gfc_init_block (&tmpblock); - gfc_conv_descriptor_span_set (&tmpblock, sym->backend_decl, - build_int_cst (gfc_array_index_type, 0)); - gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), - NULL_TREE); - } - if (sym->ts.type == BT_CLASS && (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; - DECL_INITIAL (sym->backend_decl) - = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp); + = gfc_build_default_class_descriptor (TREE_TYPE (sym->backend_decl), + sym->ts); TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1; } else if ((sym->attr.dimension || sym->attr.codimension @@ -5144,7 +5107,8 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) gfc_conv_expr (&se, e); descriptor = se.expr; se.expr = gfc_conv_descriptor_data_addr (se.expr); - se.expr = build_fold_indirect_ref_loc (input_location, se.expr); + se.expr = build_fold_indirect_ref_loc (input_location, + se.expr); } gfc_free_expr (e); diff --git a/gcc/testsuite/gfortran.dg/class_allocate_14.f90 b/gcc/testsuite/gfortran.dg/class_allocate_14.f90 index d2514772a038..01f02ab6e47a 100644 --- a/gcc/testsuite/gfortran.dg/class_allocate_14.f90 +++ b/gcc/testsuite/gfortran.dg/class_allocate_14.f90 @@ -25,6 +25,6 @@ call sub() call sub2() end -! { dg-final { scan-tree-dump-times "static struct __class_m_T_1_0a b = {._data={.data=0B}, ._vptr=&__vtab_m_T};" 1 "original" } } +! { dg-final { scan-tree-dump-times "static struct __class_m_T_1_0a b = {._data={.data=0B, .dtype={.version=0, .rank=1}}, ._vptr=&__vtab_m_T};" 1 "original" } } ! { dg-final { scan-tree-dump-times "static struct __class_m_T_a y = {._data=0B, ._vptr=&__vtab_m_T};" 1 "original" } }