https://gcc.gnu.org/g:d69f4178f93862047cf573362c940510732e539a

commit d69f4178f93862047cf573362c940510732e539a
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Sun Apr 20 18:46:54 2025 +0200

    Correction régression partparm.f90

Diff:
---
 gcc/fortran/trans-array.cc      | 12 ++++--------
 gcc/fortran/trans-array.h       |  2 +-
 gcc/fortran/trans-descriptor.cc | 17 +++++++++--------
 gcc/fortran/trans-expr.cc       |  2 +-
 gcc/fortran/trans.cc            | 11 +++++++++--
 5 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 75802c9a0b02..2fe00be9251f 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3529,10 +3529,8 @@ build_array_ref_dim (gfc_ss *ss, tree index, tree 
spacing,
                             || ss_type == GFC_SS_INTRINSIC
                             || tmp_array
                             || non_negative_strides_array_p (info->descriptor);
-  return gfc_build_array_ref (base, index, 
-                             non_negative_stride
-                             && (!offset || integer_zerop (offset)),
-                             NULL_TREE, spacing, offset);
+  return gfc_build_array_ref (base, index, non_negative_stride, NULL_TREE,
+                             spacing, offset);
 }
 
 
@@ -6772,7 +6770,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree 
tmpdesc,
 
 /* Calculate the overall offset, including subreferences.  */
 void
-gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc,
+gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
                        bool subref, gfc_expr *expr)
 {
   tree field;
@@ -6782,15 +6780,13 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, 
tree desc,
   gfc_se start;
   int n;
 
-  tree offset = gfc_index_zero_node;
-
   bool non_negative_strides = non_negative_strides_array_p (desc);
 
   tree tmp = gfc_conv_array_data (desc);
   tree array = build_fold_indirect_ref_loc (input_location, tmp);
 
   tmp = gfc_build_array_ref (array, gfc_index_zero_node, non_negative_strides,
-                            gfc_index_zero_node, NULL_TREE);
+                            gfc_index_zero_node, NULL_TREE, offset);
 
   /* Offset the data pointer for pointer assignments from arrays with
      subreferences; e.g. my_integer => my_type(:)%integer_component.  */
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 73322a227a5f..d52c1a859459 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -147,7 +147,7 @@ void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, 
gfc_expr *, locus *);
 void gfc_conv_tmp_array_ref (gfc_se * se);
 
 /* Calculate the overall offset, including subreferences.  */
-void gfc_get_dataptr_offset (stmtblock_t*, tree, tree, bool, gfc_expr*);
+void gfc_get_dataptr_offset (stmtblock_t*, tree, tree, tree, bool, gfc_expr*);
 /* Obtain the span of an array.  */
 tree gfc_get_array_span (tree, gfc_expr *);
 /* Evaluate an array expression.  */
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index cb2dd86f6522..3e65b5ad93a3 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2481,7 +2481,7 @@ gfc_copy_descriptor (stmtblock_t *block, tree dest, tree 
src,
 
   /* Add any offsets from subreferences.  */
   if (subref)
-    gfc_get_dataptr_offset (block, dest, src, subref, src_expr);
+    gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr);
 
   /* ....and set the span field.  */
   tree tmp2;
@@ -3055,12 +3055,13 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree 
src, gfc_expr *src_expr,
     dtype = gfc_get_dtype (TREE_TYPE (src), &rank);
   gfc_conv_descriptor_dtype_set (block, dest, dtype);
 
-  /* The offset from the 1st element in the section.  */
-  tree offset = gfc_index_zero_node;
-
   /* The 1st element in the section.  */
+  tree base = gfc_index_zero_node;
   if (src_expr->ts.type == BT_CHARACTER && src_expr->rank == 0 && corank)
-    offset = gfc_conv_descriptor_elem_len_get (dest);
+    base = gfc_conv_descriptor_elem_len_get (dest);
+
+  /* The offset from the 1st element in the section.  */
+  tree offset = gfc_index_zero_node;
 
   for (int n = 0; n < ndim; n++)
     {
@@ -3087,8 +3088,8 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree 
src, gfc_expr *src_expr,
                             start, tmp);
       tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
                             tmp, spacing);
-      offset = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
-                               offset, tmp);
+      base = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
+                             base, tmp);
 
       if (info->ref
          && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
@@ -3150,7 +3151,7 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree 
src, gfc_expr *src_expr,
 
   if (data_needed)
     /* Point the data pointer at the 1st element in the section.  */
-    gfc_get_dataptr_offset (block, dest, src, subref, src_expr);
+    gfc_get_dataptr_offset (block, dest, src, base, subref, src_expr);
   else
     gfc_conv_descriptor_data_set (block, dest,
                                  gfc_index_zero_node);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 2dcb684e326a..873d26ac35e9 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5938,7 +5938,7 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr 
*e, gfc_symbol *fsym)
       if (POINTER_TYPE_P (TREE_TYPE (gfc)))
        gfc = build_fold_indirect_ref_loc (input_location, gfc);
       else if (is_subref_array (e) && e->ts.type != BT_CHARACTER)
-        gfc_get_dataptr_offset (&se.pre, gfc, gfc, true, e);
+       gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL_TREE, true, e);
     }
   if (e->ts.type == BT_CHARACTER)
     {
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 75825dcdc80f..53283264a609 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -435,8 +435,15 @@ gfc_build_array_ref (tree type, tree base, tree index, 
bool non_negative_offset,
                                     build_int_cst (gfc_array_index_type,
                                                    elt_align));
        }
-      return build4_loc (input_location, ARRAY_REF, type, base, index,
-                        min_idx, spacing);
+      tree ref = build4_loc (input_location, ARRAY_REF, type, base, index,
+                            min_idx, spacing);
+      if (!offset || integer_zerop (offset))
+       return ref;
+
+      tree addr = gfc_build_addr_expr (NULL_TREE, ref);
+
+      tree ptr = fold_build_pointer_plus_loc (input_location, addr, offset);
+      return build_fold_indirect_ref_loc (input_location, ptr);
     }
   /* Otherwise use pointer arithmetic.  */
   else

Reply via email to