https://gcc.gnu.org/g:6696b3e5358efba567fc8f64c150f154e51ebdec

commit 6696b3e5358efba567fc8f64c150f154e51ebdec
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Tue Apr 29 18:40:50 2025 +0200

    Restauration intrinsic stride (correction régression finalize_17)

Diff:
---
 gcc/fortran/class.cc           | 43 +++++++++++++++++++++++-------------------
 gcc/fortran/intrinsic.cc       |  8 ++++++++
 gcc/fortran/trans-intrinsic.cc | 32 +++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 23d8701ac44f..e92760db51dd 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1343,14 +1343,12 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol 
*ptr,
      offset = 0
      do idx2 = 1, rank
        offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
-     end do
-     offset = offset * byte_stride.  */
+     end do  */
 
 static gfc_code*
 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
                         gfc_symbol *strides, gfc_symbol *sizes,
-                        gfc_symbol *byte_stride, gfc_expr *rank,
-                        gfc_code *block, gfc_namespace *sub_ns)
+                        gfc_expr *rank, gfc_code *block, gfc_namespace *sub_ns)
 {
   gfc_iterator *iter;
   gfc_expr *expr, *expr2;
@@ -1443,17 +1441,6 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol 
*idx2, gfc_symbol *offset,
   block->block->next->expr2->ts = idx->ts;
   block->block->next->expr2->where = gfc_current_locus;
 
-  /* After the loop:  offset = offset * byte_stride.  */
-  block->next = gfc_get_code (EXEC_ASSIGN);
-  block = block->next;
-  block->expr1 = gfc_lval_expr_from_sym (offset);
-  block->expr2 = gfc_get_expr ();
-  block->expr2->expr_type = EXPR_OP;
-  block->expr2->value.op.op = INTRINSIC_TIMES;
-  block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
-  block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
-  block->expr2->ts = block->expr2->value.op.op1->ts;
-  block->expr2->where = gfc_current_locus;
   return block;
 }
 
@@ -1926,10 +1913,29 @@ generate_finalization_wrapper (gfc_symbol *derived, 
gfc_namespace *ns,
   last_code->ext.iterator = iter;
   last_code->block = gfc_get_code (EXEC_DO);
 
-  /* sizes(idx) = ...  */
+  /* strides(idx) = _F._stride(array,dim=idx).  */
   last_code->block->next = gfc_get_code (EXEC_ASSIGN);
   block = last_code->block->next;
 
+  block->expr1 = gfc_lval_expr_from_sym (strides);
+  block->expr1->ref = gfc_get_ref ();
+  block->expr1->ref->type = REF_ARRAY;
+  block->expr1->ref->u.ar.type = AR_ELEMENT;
+  block->expr1->ref->u.ar.dimen = 1;
+  block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
+  block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
+  block->expr1->ref->u.ar.as = strides->as;
+
+  block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
+                                          gfc_current_locus, 2,
+                                          gfc_lval_expr_from_sym (array),
+                                          gfc_lval_expr_from_sym (idx));
+
+  /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind).  */
+  block->next = gfc_get_code (EXEC_ASSIGN);
+  block = block->next;
+
+  /* sizes(idx) = ...  */
   block->expr1 = gfc_lval_expr_from_sym (sizes);
   block->expr1->ref = gfc_get_ref ();
   block->expr1->ref->type = REF_ARRAY;
@@ -2146,8 +2152,7 @@ generate_finalization_wrapper (gfc_symbol *derived, 
gfc_namespace *ns,
 
          /* Offset calculation.  */
          block = finalization_get_offset (idx, idx2, offset, strides, sizes,
-                                          byte_stride, rank, block->block,
-                                          sub_ns);
+                                          rank, block->block, sub_ns);
 
          /* Create code for
             CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), 
c_intptr)
@@ -2217,7 +2222,7 @@ finish_assumed_rank:
 
       /* Offset calculation.  */
       block = finalization_get_offset (idx, idx2, offset, strides, sizes,
-                                      byte_stride, rank, last_code->block,
+                                      rank, last_code->block,
                                       sub_ns);
 
       /* Create code for
diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc
index 417d285ec308..30f532b5766b 100644
--- a/gcc/fortran/intrinsic.cc
+++ b/gcc/fortran/intrinsic.cc
@@ -3125,6 +3125,14 @@ add_functions (void)
 
   make_generic ("size", GFC_ISYM_SIZE, GFC_STD_F95);
 
+  /* Obtain the stride for a given dimensions; to be used only internally.
+     "make_from_module" makes it inaccessible for external users.  */
+  add_sym_2 (GFC_PREFIX ("stride"), GFC_ISYM_STRIDE, CLASS_INQUIRY, ACTUAL_NO,
+            BT_INTEGER, gfc_index_integer_kind, GFC_STD_GNU,
+            NULL, NULL, gfc_resolve_stride,
+            ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL);
+  make_from_module();
+
   add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, CLASS_INQUIRY, ACTUAL_NO,
             BT_INTEGER, ii, GFC_STD_GNU,
             gfc_check_sizeof, gfc_simplify_sizeof, NULL,
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 43e3ebff3bee..12a317440cff 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -2745,6 +2745,34 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
 }
 
 
+static void
+conv_intrinsic_stride (gfc_se * se, gfc_expr * expr)
+{
+  gfc_actual_arglist *array_arg;
+  gfc_actual_arglist *dim_arg;
+  gfc_se argse;
+  tree desc, tmp;
+
+  array_arg = expr->value.function.actual;
+  dim_arg = array_arg->next;
+
+  gcc_assert (array_arg->expr->expr_type == EXPR_VARIABLE);
+
+  gfc_init_se (&argse, NULL);
+  gfc_conv_expr_descriptor (&argse, array_arg->expr);
+  gfc_add_block_to_block (&se->pre, &argse.pre);
+  gfc_add_block_to_block (&se->post, &argse.post);
+  desc = argse.expr;
+
+  gcc_assert (dim_arg->expr);
+  gfc_init_se (&argse, NULL);
+  gfc_conv_expr_type (&argse, dim_arg->expr, gfc_array_index_type);
+  gfc_add_block_to_block (&se->pre, &argse.pre);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+                        argse.expr, gfc_index_one_node);
+  se->expr = gfc_conv_descriptor_spacing_get (desc, tmp);
+}
+
 static void
 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
 {
@@ -11272,6 +11300,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * 
expr)
       gfc_conv_intrinsic_spacing (se, expr);
       break;
 
+    case GFC_ISYM_STRIDE:
+      conv_intrinsic_stride (se, expr);
+      break;
+
     case GFC_ISYM_SUM:
       gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false);
       break;

Reply via email to