diff options
author | Andre Vehreschild <vehre@gcc.gnu.org> | 2024-06-07 08:57:36 +0200 |
---|---|---|
committer | Andre Vehreschild <vehre@gcc.gnu.org> | 2024-06-28 09:17:35 +0200 |
commit | 3f8ce76f53d0fd6bb871f0d85d29be96c5d10c81 (patch) | |
tree | d7d83d84991d04d4c9c3c2090c6b1f56c6412494 /gcc/fortran | |
parent | 07e915913b6b3d4e6e210f6dbc8e7e0e8ea594c4 (diff) | |
download | gcc-3f8ce76f53d0fd6bb871f0d85d29be96c5d10c81.zip gcc-3f8ce76f53d0fd6bb871f0d85d29be96c5d10c81.tar.gz gcc-3f8ce76f53d0fd6bb871f0d85d29be96c5d10c81.tar.bz2 |
Use gfc_reset_vptr more consistently.
The vptr for a class type is set in various ways in different
locations. Refactor the use and simplify code.
gcc/fortran/ChangeLog:
* trans-array.cc (structure_alloc_comps): Use reset_vptr.
* trans-decl.cc (gfc_trans_deferred_vars): Same.
(gfc_generate_function_code): Same.
* trans-expr.cc (gfc_reset_vptr): Allow supplying the class
type.
(gfc_conv_procedure_call): Use reset_vptr.
* trans-intrinsic.cc (gfc_conv_intrinsic_transfer): Same.
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/trans-array.cc | 34 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.cc | 19 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.cc | 57 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.cc | 10 |
4 files changed, 38 insertions, 82 deletions
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 26237f4..510f429 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -9885,15 +9885,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, else { /* Build the vtable address and set the vptr with it. */ - tree vtab; - gfc_symbol *vtable; - vtable = gfc_find_derived_vtab (c->ts.u.derived); - vtab = vtable->backend_decl; - if (vtab == NULL_TREE) - vtab = gfc_get_symbol_decl (vtable); - vtab = gfc_build_addr_expr (NULL, vtab); - vtab = fold_convert (TREE_TYPE (tmp), vtab); - gfc_add_modify (&tmpblock, tmp, vtab); + gfc_reset_vptr (&tmpblock, nullptr, tmp, c->ts.u.derived); } } @@ -9924,15 +9916,13 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, && (CLASS_DATA (c)->attr.allocatable || CLASS_DATA (c)->attr.class_pointer)) { - tree vptr_decl; + tree class_ref; /* Allocatable CLASS components. */ - comp = fold_build3_loc (input_location, COMPONENT_REF, ctype, - decl, cdecl, NULL_TREE); - - vptr_decl = gfc_class_vptr_get (comp); + class_ref = fold_build3_loc (input_location, COMPONENT_REF, ctype, + decl, cdecl, NULL_TREE); - comp = gfc_class_data_get (comp); + comp = gfc_class_data_get (class_ref); if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp))) gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node); @@ -9947,19 +9937,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, /* The dynamic type of a disassociated pointer or unallocated allocatable variable is its declared type. An unlimited polymorphic entity has no declared type. */ - if (!UNLIMITED_POLY (c)) - { - vtab = gfc_find_derived_vtab (c->ts.u.derived); - if (!vtab->backend_decl) - gfc_get_symbol_decl (vtab); - tmp = gfc_build_addr_expr (NULL_TREE, vtab->backend_decl); - } - else - tmp = build_int_cst (TREE_TYPE (vptr_decl), 0); - - tmp = fold_build2_loc (input_location, MODIFY_EXPR, - void_type_node, vptr_decl, tmp); - gfc_add_expr_to_block (&fnblock, tmp); + gfc_reset_vptr (&fnblock, nullptr, class_ref, c->ts.u.derived); cmp_has_alloc_comps = false; } diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 8d4f06a..11247dd 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -5107,26 +5107,11 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) if (sym->ts.type == BT_CLASS) { /* Initialize _vptr to declared type. */ - gfc_symbol *vtab; - tree rhs; - gfc_save_backend_locus (&loc); gfc_set_backend_locus (&sym->declared_at); e = gfc_lval_expr_from_sym (sym); - gfc_add_vptr_component (e); - gfc_init_se (&se, NULL); - se.want_pointer = 1; - gfc_conv_expr (&se, e); + gfc_reset_vptr (&init, e); gfc_free_expr (e); - if (UNLIMITED_POLY (sym)) - rhs = build_int_cst (TREE_TYPE (se.expr), 0); - else - { - vtab = gfc_find_derived_vtab (sym->ts.u.derived); - rhs = gfc_build_addr_expr (TREE_TYPE (se.expr), - gfc_get_symbol_decl (vtab)); - } - gfc_add_modify (&init, se.expr, rhs); gfc_restore_backend_locus (&loc); } @@ -7968,7 +7953,7 @@ gfc_generate_function_code (gfc_namespace * ns) fold_convert (TREE_TYPE (tmp), null_pointer_node)); gfc_reset_vptr (&init, nullptr, result, - CLASS_DATA (sym->result)->ts.u.derived); + sym->result->ts.u.derived); } else if (sym->ts.type == BT_DERIVED && !sym->attr.allocatable) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 558a738..454b875 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -532,12 +532,12 @@ gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold, /* Reset the vptr to the declared type, e.g. after deallocation. Use the variable in CLASS_CONTAINER if available. Otherwise, recreate - one with e or derived. At least one of the two has to be set. The generated - assignment code is added at the end of BLOCK. */ + one with e or class_type. At least one of the two has to be set. The + generated assignment code is added at the end of BLOCK. */ void gfc_reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_container, - gfc_symbol *derived) + gfc_symbol *class_type) { tree vptr = NULL_TREE; @@ -564,15 +564,31 @@ gfc_reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_container, if (vptr == NULL_TREE) return; - if (UNLIMITED_POLY (e)) + if (UNLIMITED_POLY (e) + || UNLIMITED_POLY (class_type) + /* When the class_type's source is not a symbol (e.g. a component's ts), + then look at the _data-components type. */ + || (class_type != NULL && class_type->ts.type == BT_UNKNOWN + && class_type->components && class_type->components->ts.u.derived + && class_type->components->ts.u.derived->attr.unlimited_polymorphic)) gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0)); else { - gfc_symbol *vtab; + gfc_symbol *vtab, *type = nullptr; tree vtable; + if (e) + type = e->ts.u.derived; + else if (class_type) + { + if (class_type->ts.type == BT_CLASS) + type = CLASS_DATA (class_type)->ts.u.derived; + else + type = class_type; + } + gcc_assert (type); /* Return the vptr to the address of the declared type. */ - vtab = gfc_find_derived_vtab (derived ? derived : e->ts.u.derived); + vtab = gfc_find_derived_vtab (type); vtable = vtab->backend_decl; if (vtable == NULL_TREE) vtable = gfc_get_symbol_decl (vtab); @@ -6872,29 +6888,14 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, NULL_TREE, true, e, e->ts, cls); gfc_add_expr_to_block (&block, tmp); - tmp = fold_build2_loc (input_location, MODIFY_EXPR, - void_type_node, ptr, - null_pointer_node); - gfc_add_expr_to_block (&block, tmp); + gfc_add_modify (&block, ptr, + fold_convert (TREE_TYPE (ptr), + null_pointer_node)); - if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym)) - { - gfc_add_modify (&block, ptr, - fold_convert (TREE_TYPE (ptr), - null_pointer_node)); - gfc_add_expr_to_block (&block, tmp); - } - else if (fsym->ts.type == BT_CLASS) - { - gfc_symbol *vtab; - vtab = gfc_find_derived_vtab (fsym->ts.u.derived); - tmp = gfc_get_symbol_decl (vtab); - tmp = gfc_build_addr_expr (NULL_TREE, tmp); - ptr = gfc_class_vptr_get (parmse.expr); - gfc_add_modify (&block, ptr, - fold_convert (TREE_TYPE (ptr), tmp)); - gfc_add_expr_to_block (&block, tmp); - } + if (fsym->ts.type == BT_CLASS) + gfc_reset_vptr (&block, nullptr, + build_fold_indirect_ref (parmse.expr), + fsym->ts.u.derived); if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 9683970..ac7fcd2 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -8815,15 +8815,7 @@ scalar_transfer: /* For CLASS results, set the _vptr. */ if (mold_expr->ts.type == BT_CLASS) - { - tree vptr; - gfc_symbol *vtab; - vptr = gfc_class_vptr_get (tmpdecl); - vtab = gfc_find_derived_vtab (source_expr->ts.u.derived); - gcc_assert (vtab); - tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); - gfc_add_modify (&se->pre, vptr, fold_convert (TREE_TYPE (vptr), tmp)); - } + gfc_reset_vptr (&se->pre, nullptr, tmpdecl, source_expr->ts.u.derived); se->expr = tmpdecl; } |