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

commit f06001181094a5e060a5c7d6858a5114cf4d0950
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Thu Apr 10 11:53:42 2025 +0200

    Correction ICEs ISO_Fortran_binding_10

Diff:
---
 gcc/fortran/trans-array.cc      | 49 +++++++++++++++++++++++++++++++++++++++--
 gcc/fortran/trans-descriptor.cc |  5 ++---
 gcc/fortran/trans-types.cc      |  3 ++-
 gcc/fortran/trans.cc            | 16 ++++++--------
 4 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 4c8136ba6a1d..00e262f7d02e 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -2094,6 +2094,15 @@ gfc_constant_array_constructor_p (gfc_constructor_base 
base)
 }
 
 
+static void
+append_constructor (vec<constructor_elt, va_gc> *v, tree t)
+{
+  unsigned len = vec_safe_length (v);
+  tree idx = build_int_cst (gfc_array_index_type, len);
+  CONSTRUCTOR_APPEND_ELT (v, idx, t);
+}
+
+
 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
    and the tree type of it's elements, TYPE, return a static constant
    variable that is compile-time initialized.  */
@@ -2122,8 +2131,7 @@ gfc_build_constant_array_constructor (gfc_expr * expr, 
tree type)
       else if (POINTER_TYPE_P (type))
        se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
                                       se.expr);
-      CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
-                              se.expr);
+      append_constructor (v, se.expr);
       c = gfc_constructor_next (c);
       nelem++;
     }
@@ -2160,6 +2168,43 @@ gfc_build_constant_array_constructor (gfc_expr * expr, 
tree type)
       gfc_free_expr (as.upper[i]);
     }
 
+  if (expr->shape && expr->rank > 1)
+    {
+      vec<constructor_elt, va_gc> *vsrc = v;
+
+      for (int r = 0; r < expr->rank - 1; r++)
+       {
+         vec<constructor_elt, va_gc> *vdest = nullptr;
+         unsigned sidx = 0;
+
+         tree type = tmptype;
+         for (int j = expr->rank - 1; j > r; j--)
+           {
+             gcc_assert (GFC_ARRAY_TYPE_P (type)); 
+             type = TREE_TYPE (type);
+           }
+
+         int len = (int) mpz_get_si (expr->shape[r]);
+
+         while (sidx != vec_safe_length (vsrc))
+           {
+             vec<constructor_elt, va_gc> *vtmp = nullptr;
+
+             for (int i = 0; i < len; i++)
+               {
+                 append_constructor (vtmp, (*vsrc)[sidx].value);
+                 sidx++;
+               }
+
+             append_constructor (vdest, build_constructor (type, vtmp));
+           }
+
+         vsrc = vdest;
+       }
+
+      v = vsrc;
+    }
+
   init = build_constructor (tmptype, v);
 
   TREE_CONSTANT (init) = 1;
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 66a1019207ad..f9cc1ae20066 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -166,9 +166,8 @@ gfc_get_cfi_dim_sm (tree desc, tree idx)
 #define OFFSET_FIELD 1
 #define DTYPE_FIELD 2
 #define SPAN_FIELD 3
-#define ALIGN_FIELD 4
-#define DIMENSION_FIELD 5
-#define CAF_TOKEN_FIELD 6
+#define DIMENSION_FIELD 4
+#define CAF_TOKEN_FIELD 5
 
 #define SPACING_SUBFIELD 0
 #define LBOUND_SUBFIELD 1
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 69021347d9fa..f559b2bd384f 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2192,7 +2192,8 @@ gfc_get_array_type_bounds (tree etype, int dimen, int 
codimen, tree * lbound,
   if (packed == 0)
     {
       stride = gfc_index_one_node;
-      spacing = TYPE_SIZE_UNIT (etype);
+      spacing = fold_convert_loc (input_location, gfc_array_index_type,
+                                 TYPE_SIZE_UNIT (etype));
     }
   else
     {
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 152e19f536ac..c77bd72b3fb2 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -423,15 +423,11 @@ gfc_build_array_ref (tree type, tree base, tree index, 
bool non_negative_offset,
 
   if (non_negative_offset)
     {
-      tree align = build_int_cst (gfc_array_index_type,
-                                 TYPE_ALIGN_UNIT (type));
-      tree elt_unit_cnt = fold_build2_loc (input_location, EXACT_DIV_EXPR,
-                                          gfc_array_index_type, spacing,
-                                          align);
-      tree min_val = fold_build1_loc (input_location, NEGATE_EXPR,
-                                     gfc_array_index_type, offset);
+      tree min_val = offset ? fold_build1_loc (input_location, NEGATE_EXPR,
+                                              gfc_array_index_type, offset)
+                           : NULL_TREE;
       return build4_loc (input_location, ARRAY_REF, type, base, index,
-                        min_val, elt_unit_cnt);
+                        min_val, spacing);
     }
   /* Otherwise use pointer arithmetic.  */
   else
@@ -455,6 +451,8 @@ gfc_build_array_ref (tree type, tree base, tree index, bool 
non_negative_offset,
       tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
                                           gfc_array_index_type,
                                           zero_based_index, spacing);
+      offset_bytes = fold_convert_loc (input_location, sizetype,
+                                      offset_bytes);
 
       tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
 
@@ -486,7 +484,7 @@ gfc_build_array_ref (tree base, tree index, bool 
non_negative_offset,
       return base;
     }
 
-  return gfc_build_array_ref (TREE_TYPE (type), index, non_negative_offset,
+  return gfc_build_array_ref (TREE_TYPE (type), base, index, 
non_negative_offset,
                              offset, spacing);
 }

Reply via email to