https://gcc.gnu.org/g:098eab32781a92843d5485e9b8a25b440fef8ddf

commit 098eab32781a92843d5485e9b8a25b440fef8ddf
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Mar 7 13:24:23 2025 +0100

    Correction actual_array_offset_1.f90

Diff:
---
 gcc/fortran/trans-array.cc | 75 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 57 insertions(+), 18 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 480df9829dec..b8fc0c4bea3e 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5692,6 +5692,35 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, 
bool subscript,
 }
 
 
+/* A simple reference can be accessed with a pointer and
+   a constant offset.  */
+bool
+simple_reference_p (tree data_ref)
+{
+  bool seen_dereference = false;
+  while (true)
+    {
+      if (DECL_P (data_ref))
+       return true;
+
+      if (TREE_CODE (data_ref) == INDIRECT_REF)
+       {
+         if (seen_dereference)
+           return false;
+
+         seen_dereference = true;
+         data_ref = TREE_OPERAND (data_ref, 0);
+       }
+      else if (TREE_CODE (data_ref) == COMPONENT_REF)
+       data_ref = TREE_OPERAND (data_ref, 0);
+      else if (TREE_CODE (data_ref) == NOP_EXPR)
+       data_ref = TREE_OPERAND (data_ref, 0);
+      else
+       return false;
+    }
+}
+
+
 /* Translate expressions for the descriptor and data pointer of a SS.  */
 /*GCC ARRAYS*/
 
@@ -5712,24 +5741,34 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * 
ss, int base)
   se.descriptor_only = 1;
   gfc_conv_expr_lhs (&se, ss_info->expr);
   gfc_add_block_to_block (block, &se.pre);
-  info->descriptor = se.expr;
-  if (TREE_CODE (info->descriptor) == INDIRECT_REF)
-    {
-      tree ptr = TREE_OPERAND (info->descriptor, 0);
-      ptr = gfc_evaluate_now (ptr, block);
-      TREE_OPERAND (info->descriptor, 0) = ptr;
-    }
-  else if (TREE_CODE (info->descriptor) == COMPONENT_REF)
-    {
-      tree parent_ref = TREE_OPERAND (info->descriptor, 0);
-      tree parent_ptr_type = build_pointer_type (TREE_TYPE (parent_ref));
-      tree ptr = fold_build1_loc (input_location, ADDR_EXPR,
-                                 parent_ptr_type, parent_ref);
-      ptr = gfc_evaluate_now (ptr, block);
-      tree deref = fold_build1_loc (input_location, INDIRECT_REF,
-                                   TREE_TYPE (parent_ref),
-                                   ptr);
-      TREE_OPERAND (info->descriptor, 0) = deref;
+  if (simple_reference_p (se.expr))
+    info->descriptor = se.expr;
+  else
+    {
+      tree desc = se.expr;
+      STRIP_NOPS (desc);
+      if (TREE_CODE (desc) == INDIRECT_REF)
+       {
+         tree ptr = TREE_OPERAND (desc, 0);
+         ptr = gfc_evaluate_now (ptr, block);
+         TREE_OPERAND (desc, 0) = ptr;
+         info->descriptor = se.expr;
+       }
+      else if (TREE_CODE (desc) == COMPONENT_REF)
+       {
+         tree parent_ref = TREE_OPERAND (desc, 0);
+         tree parent_ptr_type = build_pointer_type (TREE_TYPE (parent_ref));
+         tree ptr = fold_build1_loc (input_location, ADDR_EXPR,
+                                     parent_ptr_type, parent_ref);
+         ptr = gfc_evaluate_now (ptr, block);
+         tree deref = fold_build1_loc (input_location, INDIRECT_REF,
+                                       TREE_TYPE (parent_ref),
+                                       ptr);
+         TREE_OPERAND (desc, 0) = deref;
+         info->descriptor = se.expr;
+       }
+      else
+       info->descriptor = gfc_evaluate_now (se.expr, block);
     }
   ss_info->string_length = se.string_length;
   ss_info->class_container = se.class_container;

Reply via email to