https://gcc.gnu.org/g:871741486743f74a32d44f6f518c42eb3b150c03

commit 871741486743f74a32d44f6f518c42eb3b150c03
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri May 23 20:13:51 2025 +0200

    Contournement régression zero_sized_15

Diff:
---
 gcc/fortran/trans-array.cc | 33 ++++++++++++++++++++++++++-------
 gcc/fortran/trans-types.cc | 28 +++++++++++++++++++++++++---
 2 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b28d65445bc6..43e5e1e756bc 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -2435,6 +2435,8 @@ trans_array_constructor (gfc_ss * ss, locus * where)
       /* Complex character array constructors should have been taken care of
         and not end up here.  */
       gcc_assert (ss_info->string_length);
+      ss_info->string_length = gfc_evaluate_now (ss_info->string_length,
+                                                &outer_loop->pre);
 
       store_backend_decl (&expr->ts.u.cl, ss_info->string_length, 
force_new_cl);
 
@@ -5518,10 +5520,15 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
 
       /* Make absolutely sure that this is a complete type.  */
       if (tmp_ss_info->string_length)
-       tmp_ss_info->data.temp.type
-               = gfc_get_character_type_len_for_eltype
-                       (TREE_TYPE (tmp_ss_info->data.temp.type),
-                        tmp_ss_info->string_length);
+       {
+         tree len = tmp_ss_info->string_length;
+         len = gfc_evaluate_now (len, &outermost_loop (loop)->pre);
+         tmp_ss_info->string_length = len;
+         tmp_ss_info->data.temp.type
+                 = gfc_get_character_type_len_for_eltype
+                         (TREE_TYPE (tmp_ss_info->data.temp.type),
+                          tmp_ss_info->string_length);
+       }
 
       tmp = tmp_ss_info->data.temp.type;
       memset (&tmp_ss_info->data.array, 0, sizeof (gfc_array_info));
@@ -8084,9 +8091,21 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, 
bool g77,
 
   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
     {
-      get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
-      expr->ts.u.cl->backend_decl = tmp;
-      se->string_length = tmp;
+      if (expr->ts.u.cl->length_from_typespec)
+       {
+         gfc_se len_se;
+         gfc_init_se (&len_se, NULL);
+         gfc_conv_expr_val (&len_se, expr->ts.u.cl->length);
+         gfc_add_block_to_block (&se->pre, &len_se.pre);
+         expr->ts.u.cl->backend_decl = len_se.expr;
+         se->string_length = len_se.expr;
+       }
+      else
+       {
+         get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
+         expr->ts.u.cl->backend_decl = tmp;
+         se->string_length = tmp;
+       }
     }
 
   /* Is this the result of the enclosing procedure?  */
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 9568d8f821ab..c7433f11bed7 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2303,12 +2303,34 @@ gfc_get_array_type_bounds (tree etype, int dimen, int 
codimen, tree * lbound,
 
   /* We define data as an array with the correct size if possible.
      Much better than doing pointer arithmetic.  */
+  bool known_zero_size = false;
   if (stride)
-    rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node,
-                             int_const_binop (MINUS_EXPR, stride,
-                                              build_int_cst (TREE_TYPE 
(stride), 1)));
+    {
+      tree range_bound = int_const_binop (MINUS_EXPR, stride,
+                                         build_int_cst (TREE_TYPE (stride),
+                                                        1));
+      rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node,
+                               range_bound);
+      if (integer_minus_onep (range_bound))
+       known_zero_size = true;
+    }
   else
     rtype = gfc_array_range_type;
+  if (known_zero_size
+      && TREE_CODE (etype) == ARRAY_TYPE
+      && TYPE_DOMAIN (etype)
+      && TYPE_MAX_VALUE (TYPE_DOMAIN (etype))
+      && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (etype))) != INTEGER_CST)
+    {
+      tree elt = TREE_TYPE (etype);
+      tree domain = TYPE_DOMAIN (etype);
+      tree min = TYPE_MIN_VALUE (domain);
+      domain = build_range_type (TREE_TYPE (domain), min, min);
+      tree new_etype = build_array_type (elt, domain);
+      TYPE_STRING_FLAG (new_etype) = TYPE_STRING_FLAG (etype);
+      layout_type (new_etype);
+      etype = new_etype;
+    }
   arraytype = build_array_type (etype, rtype);
   arraytype = build_pointer_type (arraytype);
   if (restricted)

Reply via email to