https://gcc.gnu.org/g:af30c6cb49e24894c71460e870c5f3c5942fb3a8
commit af30c6cb49e24894c71460e870c5f3c5942fb3a8 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed Jul 16 22:09:17 2025 +0200 Extraction gfc_copy_descriptor Diff: --- gcc/fortran/trans-array.cc | 25 ++----------------------- gcc/fortran/trans-descriptor.cc | 32 ++++++++++++++++++++++++++++++++ gcc/fortran/trans-descriptor.h | 1 + 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 360220b6cfde..8973ac241c75 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -7831,29 +7831,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) if (full && !transposed_dims (ss)) { if (se->direct_byref && !se->byref_noassign) - { - struct lang_type *lhs_ls - = TYPE_LANG_SPECIFIC (TREE_TYPE (se->expr)), - *rhs_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (desc)); - /* When only the array_kind differs, do a view_convert. */ - tmp = lhs_ls && rhs_ls && lhs_ls->rank == rhs_ls->rank - && lhs_ls->akind != rhs_ls->akind - ? build1 (VIEW_CONVERT_EXPR, TREE_TYPE (se->expr), desc) - : desc; - /* Copy the descriptor for pointer assignments. */ - gfc_add_modify (&se->pre, se->expr, tmp); - - /* Add any offsets from subreferences. */ - gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE, - subref_array_target, expr); - - /* ....and set the span field. */ - if (ss_info->expr->ts.type == BT_CHARACTER) - tmp = gfc_conv_descriptor_span_get (desc); - else - tmp = gfc_get_array_span (desc, expr); - gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp); - } + gfc_copy_descriptor (&se->pre, se->expr, desc, expr, + subref_array_target); else if (se->want_pointer) { /* We pass full arrays directly. This means that pointers and diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index b1e651c254bf..bd68a777d068 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1195,4 +1195,36 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src, gfc_conv_descriptor_offset_set (block, dest, offset); } + +void +gfc_copy_descriptor (stmtblock_t *block, tree dest, tree src, + gfc_expr *src_expr, bool subref) +{ + struct lang_type *dest_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (dest)); + struct lang_type *src_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (src)); + + /* When only the array_kind differs, do a view_convert. */ + tree tmp1; + if (dest_ls + && src_ls + && dest_ls->rank == src_ls->rank + && dest_ls->akind != src_ls->akind) + tmp1 = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dest), src); + else + tmp1 = src; + + /* Copy the descriptor for pointer assignments. */ + gfc_add_modify (block, dest, tmp1); + + /* Add any offsets from subreferences. */ + gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr); + + /* ....and set the span field. */ + tree tmp2; + if (src_expr->ts.type == BT_CHARACTER) + tmp2 = gfc_conv_descriptor_span_get (src); + else + tmp2 = gfc_get_array_span (src, src_expr); + gfc_conv_descriptor_span_set (block, dest, tmp2); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index ec0306ead91a..b1fee3b33a78 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -109,5 +109,6 @@ int gfc_descriptor_rank (tree); void gfc_conv_remap_descriptor (stmtblock_t *, tree, tree, int, const gfc_array_ref &as); void gfc_conv_shift_descriptor (stmtblock_t *, tree, tree, int, tree); +void gfc_copy_descriptor (stmtblock_t *, tree, tree, gfc_expr *, bool); #endif /* GFC_TRANS_DESCRIPTOR_H */