https://gcc.gnu.org/g:1bc10b59c053a883d84ebe318b090eb258ae91b1

commit 1bc10b59c053a883d84ebe318b090eb258ae91b1
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Mon Feb 17 22:59:01 2025 +0100

    Correction régression pr108889.f90 realloc_on_assign*

Diff:
---
 gcc/fortran/trans-array.cc | 75 +++++++++++++++++++++++++++++++++++-----------
 gcc/fortran/trans-expr.cc  | 23 --------------
 2 files changed, 58 insertions(+), 40 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index fd83c6ae66a7..b4fd623f5cf7 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5742,12 +5742,15 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * 
ss, int base)
                && DECL_P (TREE_OPERAND (tmp, 0)))
            || (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
                && TREE_CODE (se.expr) == COMPONENT_REF
-               && GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (se.expr, 0))))))
+               && GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (se.expr, 0)))))
+         && !ss->is_alloc_lhs)
        tmp = gfc_evaluate_now (tmp, block);
       info->data = tmp;
 
       tmp = gfc_conv_array_offset (se.expr);
-      info->offset = gfc_evaluate_now (tmp, block);
+      if (!ss->is_alloc_lhs)
+       tmp = gfc_evaluate_now (tmp, block);
+      info->offset = tmp;
 
       /* Make absolutely sure that the saved_offset is indeed saved
         so that the variable is still accessible after the loops
@@ -8314,7 +8317,10 @@ gfc_set_delta (gfc_loopinfo *loop)
                                     gfc_array_index_type,
                                     info->start[dim], tmp);
 
-             info->delta[dim] = gfc_evaluate_now (tmp, &outer_loop->pre);
+             if (ss->is_alloc_lhs)
+               info->delta[dim] = tmp;
+             else 
+               info->delta[dim] = gfc_evaluate_now (tmp, &outer_loop->pre);
            }
        }
     }
@@ -13598,6 +13604,52 @@ concat_str_length (gfc_expr* expr)
 }
 
 
+static void
+update_reallocated_descriptor (stmtblock_t *block, gfc_loopinfo *loop)
+{
+  for (gfc_ss *s = loop->ss; s != gfc_ss_terminator; s = s->loop_chain)
+    {
+      if (!s->is_alloc_lhs)
+       continue;
+
+      gcc_assert (s->info->type == GFC_SS_SECTION);
+      gfc_array_info *info = &s->info->data.array;
+      tree desc = info->descriptor;
+
+#define UPDATE_VALUE(field, value) \
+             do \
+               { \
+                 if ((field) && VAR_P ((field))) \
+                   { \
+                     tree val = (value); \
+                     gfc_add_modify (block, (field), val); \
+                   } \
+                 else \
+                   (field) = gfc_evaluate_now ((field), block); \
+               } \
+             while (0)
+
+      UPDATE_VALUE (info->data, gfc_conv_descriptor_data_get (desc));
+      UPDATE_VALUE (info->offset, gfc_conv_descriptor_offset_get (desc));
+      info->saved_offset = info->offset;
+      for (int i = 0; i < s->dimen; i++)
+       {
+         int dim = s->dim[i];
+         tree tree_dim = gfc_rank_cst[dim]; 
+         UPDATE_VALUE (info->start[dim],
+                       gfc_conv_descriptor_lbound_get (desc, tree_dim));
+         UPDATE_VALUE (info->end[dim],
+                       gfc_conv_descriptor_ubound_get (desc, tree_dim));
+         UPDATE_VALUE (info->stride[dim],
+                       gfc_conv_descriptor_stride_get (desc, tree_dim));
+         info->delta[dim] = gfc_evaluate_now (info->delta[dim], block);
+       }
+
+#undef UPDATE_VALUE
+    }
+}
+
+
 /* Allocate the lhs of an assignment to an allocatable array, otherwise
    reallocate it.  */
 
@@ -13690,7 +13742,7 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
       && !expr2->value.function.isym)
     expr2->ts.u.cl->backend_decl = rss->info->string_length;
 
-  gfc_start_block (&fblock);
+  gfc_init_block (&fblock);
 
   /* Since the lhs is allocatable, this must be a descriptor type.
      Get the data and array size.  */
@@ -13962,10 +14014,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
      the array offset is saved and the info.offset is used for a
      running offset.  Use the saved_offset instead.  */
   gfc_conv_descriptor_offset_set (&fblock, desc, offset);
-  if (linfo->saved_offset
-      && VAR_P (linfo->saved_offset))
-    gfc_add_modify (&fblock, linfo->saved_offset,
-                   gfc_conv_descriptor_offset_get (desc));
 
   /* Now set the deltas for the lhs.  */
   for (n = 0; n < expr1->rank; n++)
@@ -13975,8 +14023,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
       tmp = fold_build2_loc (input_location, MINUS_EXPR,
                             gfc_array_index_type, tmp,
                             loop->from[dim]);
-      if (linfo->delta[dim] && VAR_P (linfo->delta[dim]))
-       gfc_add_modify (&fblock, linfo->delta[dim], tmp);
     }
 
   /* Take into account _len of unlimited polymorphic entities, so that span
@@ -14197,17 +14243,12 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
   tmp = build3_v (COND_EXPR, cond_null, alloc_expr, realloc_expr);
   gfc_add_expr_to_block (&fblock, tmp);
 
-  /* Make sure that the scalarizer data pointer is updated.  */
-  if (linfo->data && VAR_P (linfo->data))
-    {
-      tmp = gfc_conv_descriptor_data_get (desc);
-      gfc_add_modify (&fblock, linfo->data, tmp);
-    }
-
   /* Add the label for same shape lhs and rhs.  */
   tmp = build1_v (LABEL_EXPR, jump_label2);
   gfc_add_expr_to_block (&fblock, tmp);
 
+  update_reallocated_descriptor (&fblock, loop);
+
   return gfc_finish_block (&fblock);
 }
 
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 8e7034f59420..ccb63e120715 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -12648,30 +12648,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * 
expr2, bool init_flag,
        {
          realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
          ompws_flags &= ~OMPWS_SCALARIZER_WS;
-         stmtblock_t reallocation_block;
-         gfc_init_block (&reallocation_block);
          reallocation = gfc_alloc_allocatable_for_assignment (&loop, expr1, 
expr2);
-         gfc_add_expr_to_block (&reallocation_block, reallocation);
-
-         for (gfc_ss *s = loop.ss; s != gfc_ss_terminator; s = s->loop_chain)
-           {
-             if (!s->is_alloc_lhs)
-               continue;
-
-             gcc_assert (s->info->type == GFC_SS_SECTION);
-             gfc_array_info *info = &s->info->data.array;
-             info->offset = gfc_evaluate_now (info->offset, 
&reallocation_block);
-             info->saved_offset = info->offset;
-             for (int i = 0; i < s->dimen; i++)
-               {
-                 int dim = s->dim[i];
-                 info->start[dim] = gfc_evaluate_now (info->start[dim], 
&reallocation_block);
-                 info->end[dim] = gfc_evaluate_now (info->end[dim], 
&reallocation_block);
-                 info->stride[dim] = gfc_evaluate_now (info->stride[dim], 
&reallocation_block);
-                 info->delta[dim] = gfc_evaluate_now (info->delta[dim], 
&reallocation_block);
-               }
-           }
-         reallocation = gfc_finish_block (&reallocation_block);
        }
 
       /* Start the scalarized loop body.  */

Reply via email to