aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorAndre Vehreschild <vehre@gcc.gnu.org>2024-06-07 08:57:36 +0200
committerAndre Vehreschild <vehre@gcc.gnu.org>2024-06-28 09:17:35 +0200
commit3f8ce76f53d0fd6bb871f0d85d29be96c5d10c81 (patch)
treed7d83d84991d04d4c9c3c2090c6b1f56c6412494 /gcc/fortran
parent07e915913b6b3d4e6e210f6dbc8e7e0e8ea594c4 (diff)
downloadgcc-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.cc34
-rw-r--r--gcc/fortran/trans-decl.cc19
-rw-r--r--gcc/fortran/trans-expr.cc57
-rw-r--r--gcc/fortran/trans-intrinsic.cc10
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;
}