Hi all,
this patch fixes setting the coarray bounds correctly when a scalar char array
(i.e. CHARACTER(len=N)) is passed to function expecting a coarray. And when a
derived type coarray is passed to a function expecting a polymorphically typed
coarray as argument.
Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline?
To test this one needs caf_shmem in place, because only there the required beef
to detect the issue is present. The test modifications in the last commit of
this series add a testcase for these two case.
Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From 4533298de24450b3000953b1987b31532463b263 Mon Sep 17 00:00:00 2001
From: Andre Vehreschild <[email protected]>
Date: Wed, 18 Jun 2025 09:32:19 +0200
Subject: [PATCH 3/6] Fortran: Fix coarray generation for char arrays and
derived types.
Fix the generation of a coarray, esp. its bounds, for char arrays.
When a scalar char array is used in a co_reduce the coarray part was
dropped.
Furthermore for class typed dummy arguments where derived types were
used as actual arguments the coarray generation is now done, too.
gcc/fortran/ChangeLog:
* trans-expr.cc (get_scalar_to_descriptor_type): Fix coarray
generation.
(copy_coarray_desc_part): New function to copy coarray dimensions.
(gfc_class_array_data_assign): Use the new function.
(gfc_conv_derived_to_class): Same.
---
gcc/fortran/trans-expr.cc | 68 ++++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 11 deletions(-)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index c8a207609e4..1dce7d378f0 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -90,6 +90,8 @@ static tree
get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
{
enum gfc_array_kind akind;
+ tree *lbound = NULL, *ubound = NULL;
+ int codim = 0;
if (attr.pointer)
akind = GFC_ARRAY_POINTER_CONT;
@@ -100,8 +102,16 @@ get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
if (POINTER_TYPE_P (TREE_TYPE (scalar)))
scalar = TREE_TYPE (scalar);
- return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
- akind, !(attr.pointer || attr.target));
+ if (TYPE_LANG_SPECIFIC (TREE_TYPE (scalar)))
+ {
+ struct lang_type *lang_specific = TYPE_LANG_SPECIFIC (TREE_TYPE (scalar));
+ codim = lang_specific->corank;
+ lbound = lang_specific->lbound;
+ ubound = lang_specific->ubound;
+ }
+ return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, codim, lbound,
+ ubound, 1, akind,
+ !(attr.pointer || attr.target));
}
tree
@@ -760,11 +770,43 @@ gfc_get_vptr_from_expr (tree expr)
return NULL_TREE;
}
+static void
+copy_coarray_desc_part (stmtblock_t *block, tree dest, tree src)
+{
+ tree src_type = TREE_TYPE (src);
+ if (TYPE_LANG_SPECIFIC (src_type) && TYPE_LANG_SPECIFIC (src_type)->corank)
+ {
+ struct lang_type *lang_specific = TYPE_LANG_SPECIFIC (src_type);
+ for (int c = 0; c < lang_specific->corank; ++c)
+ {
+ int dim = lang_specific->rank + c;
+ tree codim = gfc_rank_cst[dim];
+
+ if (lang_specific->lbound[dim])
+ gfc_conv_descriptor_lbound_set (block, dest, codim,
+ lang_specific->lbound[dim]);
+ else
+ gfc_conv_descriptor_lbound_set (
+ block, dest, codim, gfc_conv_descriptor_lbound_get (src, codim));
+ if (dim + 1 < lang_specific->corank)
+ {
+ if (lang_specific->ubound[dim])
+ gfc_conv_descriptor_ubound_set (block, dest, codim,
+ lang_specific->ubound[dim]);
+ else
+ gfc_conv_descriptor_ubound_set (
+ block, dest, codim,
+ gfc_conv_descriptor_ubound_get (src, codim));
+ }
+ }
+ }
+}
+
void
gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
bool lhs_type)
{
- tree tmp, tmp2, type;
+ tree lhs_dim, rhs_dim, type;
gfc_conv_descriptor_data_set (block, lhs_desc,
gfc_conv_descriptor_data_get (rhs_desc));
@@ -775,15 +817,18 @@ gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
gfc_conv_descriptor_dtype (rhs_desc));
/* Assign the dimension as range-ref. */
- tmp = gfc_get_descriptor_dimension (lhs_desc);
- tmp2 = gfc_get_descriptor_dimension (rhs_desc);
+ lhs_dim = gfc_get_descriptor_dimension (lhs_desc);
+ rhs_dim = gfc_get_descriptor_dimension (rhs_desc);
+
+ type = lhs_type ? TREE_TYPE (lhs_dim) : TREE_TYPE (rhs_dim);
+ lhs_dim = build4_loc (input_location, ARRAY_RANGE_REF, type, lhs_dim,
+ gfc_index_zero_node, NULL_TREE, NULL_TREE);
+ rhs_dim = build4_loc (input_location, ARRAY_RANGE_REF, type, rhs_dim,
+ gfc_index_zero_node, NULL_TREE, NULL_TREE);
+ gfc_add_modify (block, lhs_dim, rhs_dim);
- type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
- tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
- gfc_index_zero_node, NULL_TREE, NULL_TREE);
- tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
- gfc_index_zero_node, NULL_TREE, NULL_TREE);
- gfc_add_modify (block, tmp, tmp2);
+ /* The corank dimensions are not copied by the ARRAY_RANGE_REF. */
+ copy_coarray_desc_part (block, lhs_desc, rhs_desc);
}
/* Takes a derived type expression and returns the address of a temporary
@@ -899,6 +944,7 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym,
gfc_expr_attr (e));
gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
gfc_get_dtype (type));
+ copy_coarray_desc_part (&parmse->pre, ctree, parmse->expr);
if (optional)
parmse->expr = build3_loc (input_location, COND_EXPR,
TREE_TYPE (parmse->expr),
--
2.49.0