https://gcc.gnu.org/g:1f9bc4d088c03779b54b2c3cc19de0361b1dfcf1

commit 1f9bc4d088c03779b54b2c3cc19de0361b1dfcf1
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Thu Aug 7 11:40:21 2025 +0200

    Création gfc_conv_null_array_descriptor, gfc_conv_scalar_null_to_descriptor

Diff:
---
 gcc/fortran/trans-descriptor.cc | 33 +++++++++++++++++
 gcc/fortran/trans-descriptor.h  |  5 ++-
 gcc/fortran/trans-expr.cc       | 82 +++++++++++++++++++++++++++++++++--------
 3 files changed, 103 insertions(+), 17 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 392dd9a0a076..7e367fdbe999 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -684,3 +684,36 @@ gfc_init_absent_descriptor (stmtblock_t *block, tree descr)
   gfc_conv_descriptor_data_set (block, descr, null_pointer_node);
 }
 
+
+void
+gfc_set_scalar_descriptor (stmtblock_t *block, tree descr, tree value)
+{
+  tree etype = TREE_TYPE (value);
+
+  if (POINTER_TYPE_P (etype)
+      && TREE_TYPE (etype)
+      && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
+    etype = TREE_TYPE (etype);
+  gfc_conv_descriptor_dtype_set (block, descr,
+                                gfc_get_dtype_rank_type (0, etype));
+  gfc_conv_descriptor_data_set (block, descr, value);
+  gfc_conv_descriptor_span_set (block, descr,
+                               gfc_conv_descriptor_elem_len_get (descr));
+}
+
+
+void
+gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *expr, tree descr,
+                       tree string_length)
+{
+  tree etype = gfc_get_element_type (TREE_TYPE (descr));
+  if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
+    etype = TREE_TYPE (etype);
+  gfc_conv_descriptor_dtype_set (block, descr,
+                                gfc_get_dtype_rank_type_slen (expr->rank, 
etype,
+                                                              string_length));
+  gfc_conv_descriptor_data_set (block, descr, null_pointer_node);
+  gfc_conv_descriptor_span_set (block, descr,
+                               gfc_conv_descriptor_elem_len_get (descr));
+}
+
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 476c6d73ad8c..724f3cc711af 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -19,8 +19,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GFC_TRANS_DESCRIPTOR_H
 #define GFC_TRANS_DESCRIPTOR_H
 
-/* Build a null array descriptor constructor.  */
-void gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *, tree);
 void gfc_set_scalar_null_descriptor (stmtblock_t *block, tree, gfc_symbol *, 
gfc_expr *, tree);
 void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree,
                                    gfc_expr *, locus *);
@@ -92,7 +90,10 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, 
tree *data_off,
 
 void gfc_init_descriptor_variable (stmtblock_t *block, gfc_symbol *sym, tree 
descr);
 void gfc_init_descriptor_result (stmtblock_t *block, tree descr);
+void gfc_nullify_descriptor (stmtblock_t *block, gfc_symbol *, gfc_expr *, 
tree, tree);
 void gfc_init_static_descriptor (tree descr);
 void gfc_init_absent_descriptor (stmtblock_t *block, tree descr);
+void gfc_set_scalar_descriptor (stmtblock_t *, tree, tree);
+void gfc_nullify_descriptor (stmtblock_t *, gfc_expr *, tree, tree);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index de848bdb6630..a5f22233db5a 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -105,6 +105,56 @@ get_scalar_to_descriptor_type (tree scalar, 
symbol_attribute attr)
                                    akind, !(attr.pointer || attr.target));
 }
 
+tree
+gfc_conv_scalar_null_to_descriptor (gfc_se *se, gfc_symbol *sym, tree scalar)
+{
+  symbol_attribute attr = sym->attr;
+
+  tree type = get_scalar_to_descriptor_type (scalar, attr);
+  tree desc = gfc_create_var (type, "desc");
+  DECL_ARTIFICIAL (desc) = 1;
+
+  if (CONSTANT_CLASS_P (scalar))
+    {
+      tree tmp;
+      tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
+      gfc_add_modify (&se->pre, tmp, scalar);
+      scalar = tmp;
+    }
+  if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
+    scalar = gfc_build_addr_expr (NULL_TREE, scalar);
+
+  gfc_set_scalar_descriptor (&se->pre, desc, scalar);
+
+  return desc;
+}
+
+
+tree
+gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol *sym, gfc_expr *expr)
+{
+  tree lower[GFC_MAX_DIMENSIONS], upper[GFC_MAX_DIMENSIONS];
+
+  for (int i = 0; i < expr->rank; i++)
+    {
+      lower[i] = NULL_TREE;
+      upper[i] = NULL_TREE;
+    }
+
+  tree elt_type = gfc_typenode_for_spec (&sym->ts);
+  tree desc_type = gfc_get_array_type_bounds (elt_type, expr->rank, 0,
+                                             lower, upper, 0,
+                                             GFC_ARRAY_UNKNOWN, false);
+
+  tree desc = gfc_create_var (desc_type, "desc");
+  DECL_ARTIFICIAL (desc) = 1;
+
+  gfc_nullify_descriptor (&se->pre, expr, desc, se->string_length);
+
+  return desc;
+}
+
+
 tree
 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
 {
@@ -6633,14 +6683,29 @@ conv_null_actual (gfc_se * parmse, gfc_expr * e, 
gfc_symbol * fsym)
       if (e->ts.type == BT_CHARACTER
          && e->symtree->n.sym->ts.type == BT_CHARACTER)
        {
+         /* Ensure that a usable length is available.  */
+         if (parmse->string_length == NULL_TREE)
+           {
+             gfc_typespec *ts = &e->symtree->n.sym->ts;
+
+             if (ts->u.cl->length != NULL
+                 && ts->u.cl->length->expr_type == EXPR_CONSTANT)
+               gfc_conv_const_charlen (ts->u.cl);
+
+             if (ts->u.cl->backend_decl)
+               parmse->string_length = ts->u.cl->backend_decl;
+           }
+
          /* MOLD is present.  Substitute a temporary character NULL pointer.
             For an assumed-rank dummy we need a descriptor that passes the
             correct rank.  */
          if (fsym->as && fsym->as->type == AS_ASSUMED_RANK)
            {
              tree tmp = parmse->expr;
-             tmp = gfc_conv_scalar_to_descriptor (parmse, tmp, fsym->attr);
-             gfc_conv_descriptor_rank_set (&parmse->pre, tmp, e->rank);
+             if (e->rank == 0)
+               tmp = gfc_conv_scalar_null_to_descriptor (parmse, fsym, tmp);
+             else
+               tmp = gfc_conv_null_array_descriptor (parmse, fsym, e);
              parmse->expr = gfc_build_addr_expr (NULL_TREE, tmp);
            }
          else
@@ -6650,19 +6715,6 @@ conv_null_actual (gfc_se * parmse, gfc_expr * e, 
gfc_symbol * fsym)
                              build_zero_cst (TREE_TYPE (tmp)));
              parmse->expr = gfc_build_addr_expr (NULL_TREE, tmp);
            }
-
-         /* Ensure that a usable length is available.  */
-         if (parmse->string_length == NULL_TREE)
-           {
-             gfc_typespec *ts = &e->symtree->n.sym->ts;
-
-             if (ts->u.cl->length != NULL
-                 && ts->u.cl->length->expr_type == EXPR_CONSTANT)
-               gfc_conv_const_charlen (ts->u.cl);
-
-             if (ts->u.cl->backend_decl)
-               parmse->string_length = ts->u.cl->backend_decl;
-           }
        }
       else if (e->ts.type == BT_UNKNOWN && parmse->string_length == NULL_TREE)
        {

Reply via email to