https://gcc.gnu.org/g:0a069e0a92dd9591fe919e14e4bec361ac96346c

commit 0a069e0a92dd9591fe919e14e4bec361ac96346c
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Feb 14 11:04:01 2025 +0100

    Factorisation descriptor_element_size

Diff:
---
 gcc/fortran/trans-array.cc | 85 +++++++++++++++++++++++++++-------------------
 1 file changed, 51 insertions(+), 34 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2ec19e44a465..00b749196446 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8282,6 +8282,46 @@ gfc_conv_descriptor_cosize (tree desc, int rank, int 
corank)
 }
 
 
+static tree
+descriptor_element_size (tree descriptor, tree expr3_elem_size,
+                        gfc_expr *expr3)
+{
+  tree type;
+  tree tmp;
+
+  type = TREE_TYPE (descriptor);
+
+  /* Obviously, if there is a SOURCE expression (expr3) we must use its element
+     size.  */
+  if (expr3_elem_size != NULL_TREE)
+    tmp = expr3_elem_size;
+  else if (expr3 != NULL)
+    {
+      if (expr3->ts.type == BT_CLASS)
+       {
+         gfc_se se_sz;
+         gfc_expr *sz = gfc_copy_expr (expr3);
+         gfc_add_vptr_component (sz);
+         gfc_add_size_component (sz);
+         gfc_init_se (&se_sz, NULL);
+         gfc_conv_expr (&se_sz, sz);
+         gfc_free_expr (sz);
+         tmp = se_sz.expr;
+       }
+      else
+       {
+         tmp = gfc_typenode_for_spec (&expr3->ts);
+         tmp = TYPE_SIZE_UNIT (tmp);
+       }
+    }
+  else
+    tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+
+  /* Convert to size_t.  */
+  return fold_convert (size_type_node, tmp);
+}
+
+
 /* Fills in an array descriptor, and returns the size of the array.
    The size will be a simple_val, ie a variable or a constant.  Also
    calculates the offset of the base.  The pointer argument overflow,
@@ -8319,7 +8359,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
                     stmtblock_t * descriptor_block, tree * overflow,
                     tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
                     tree expr3_desc, bool e3_has_nodescriptor, gfc_expr *expr,
-                    tree *element_size, bool explicit_ts)
+                    tree element_size, bool explicit_ts)
 {
   tree type;
   tree tmp;
@@ -8552,37 +8592,10 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
     }
 
   /* The stride is the number of elements in the array, so multiply by the
-     size of an element to get the total size.  Obviously, if there is a
-     SOURCE expression (expr3) we must use its element size.  */
-  if (expr3_elem_size != NULL_TREE)
-    tmp = expr3_elem_size;
-  else if (expr3 != NULL)
-    {
-      if (expr3->ts.type == BT_CLASS)
-       {
-         gfc_se se_sz;
-         gfc_expr *sz = gfc_copy_expr (expr3);
-         gfc_add_vptr_component (sz);
-         gfc_add_size_component (sz);
-         gfc_init_se (&se_sz, NULL);
-         gfc_conv_expr (&se_sz, sz);
-         gfc_free_expr (sz);
-         tmp = se_sz.expr;
-       }
-      else
-       {
-         tmp = gfc_typenode_for_spec (&expr3->ts);
-         tmp = TYPE_SIZE_UNIT (tmp);
-       }
-    }
-  else
-    tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
-
-  /* Convert to size_t.  */
-  *element_size = fold_convert (size_type_node, tmp);
+     size of an element to get the total size.  */
 
   if (rank == 0)
-    return *element_size;
+    return element_size;
 
   *nelems = gfc_evaluate_now (stride, pblock);
   stride = fold_convert (size_type_node, stride);
@@ -8592,14 +8605,14 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
      dividing.  */
   tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
                         size_type_node,
-                        TYPE_MAX_VALUE (size_type_node), *element_size);
+                        TYPE_MAX_VALUE (size_type_node), element_size);
   cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
                                        logical_type_node, tmp, stride),
                       PRED_FORTRAN_OVERFLOW);
   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
                         integer_one_node, integer_zero_node);
   cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
-                                       logical_type_node, *element_size,
+                                       logical_type_node, element_size,
                                        build_int_cst (size_type_node, 0)),
                       PRED_FORTRAN_SIZE_ZERO);
   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
@@ -8609,7 +8622,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   *overflow = gfc_evaluate_now (tmp, pblock);
 
   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
-                         stride, *element_size);
+                         stride, element_size);
 
   if (poffset != NULL)
     {
@@ -8798,6 +8811,10 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
                                  se->string_length));
 
   gfc_init_block (&set_descriptor_block);
+
+
+  element_size = descriptor_element_size (se->expr, expr3_elem_size, expr3);
+
   /* Take the corank only from the actual ref and not from the coref.  The
      later will mislead the generation of the array dimensions for allocatable/
      pointer components in derived types.  */
@@ -8807,7 +8824,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
                              &offset, lower, upper,
                              &se->pre, &set_descriptor_block, &overflow,
                              expr3_elem_size, nelems, expr3, e3_arr_desc,
-                             e3_has_nodescriptor, expr, &element_size,
+                             e3_has_nodescriptor, expr, element_size,
                              explicit_ts);
 
   if (dimension)

Reply via email to