https://gcc.gnu.org/g:4070e0df492d280628ce585fefc7f2d86eef7ed0

commit 4070e0df492d280628ce585fefc7f2d86eef7ed0
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Mon Jun 30 21:41:49 2025 +0200

    Correction régression PR97046

Diff:
---
 gcc/fortran/trans-decl.cc       | 23 ++++++-------------
 gcc/fortran/trans-descriptor.cc | 50 ++++++++++++++++++++++++++++++++++++++++-
 gcc/fortran/trans-descriptor.h  |  3 +++
 3 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index e3e41cc6c12d..69379147d57f 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -7283,25 +7283,20 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
       ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
                               ctype, build_int_cst (TREE_TYPE (ctype),
                                                     CFI_type_mask));
-      tree type = gfc_conv_descriptor_type_get (gfc_desc);
 
       /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN  */
       /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_VOID));
-      tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
-                             type,
-                             build_int_cst (TREE_TYPE (type), BT_UNKNOWN));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_VOID);
+      tmp2 = gfc_conv_descriptor_type_set (gfc_desc, BT_UNKNOWN);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_struct) BT_DERIVED else  < tmp2 >  */
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype),
                                             CFI_type_struct));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_DERIVED));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_DERIVED);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_Character) BT_CHARACTER else  < tmp2 >  */
@@ -7310,8 +7305,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype),
                              CFI_type_Character));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_CHARACTER));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_CHARACTER);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_ucs4_char) BT_CHARACTER else  < tmp2 >  */
@@ -7323,16 +7317,14 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
                              build_int_cst (TREE_TYPE (tmp),
                                             CFI_type_ucs4_char));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_CHARACTER));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_CHARACTER);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_Complex) BT_COMPLEX + cfi->elem_len/2 else  < tmp2 >  */
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype),
                              CFI_type_Complex));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_COMPLEX));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_COMPLEX);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_Integer || CFI_type_Logical || CFI_type_Real)
@@ -7350,8 +7342,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
                                             CFI_type_Real));
       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
                              cond, tmp);
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
-                            type, fold_convert (TREE_TYPE (type), ctype));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, ctype);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       gfc_add_expr_to_block (&block, tmp2);
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index a05fc1b4b573..2dc40fbdf3ee 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -163,13 +163,24 @@ gfc_get_cfi_dim_sm (tree desc, tree idx)
 #define LBOUND_SUBFIELD 1
 #define UBOUND_SUBFIELD 2
 
+
+static tree
+get_type_field (tree type, unsigned field_idx)
+{
+  tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
+  gcc_assert (field != NULL_TREE);
+
+  return field;
+}
+
+
 static tree
 gfc_get_descriptor_field (tree desc, unsigned field_idx)
 {
   tree type = TREE_TYPE (desc);
   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
 
-  tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
+  tree field = get_type_field (type, field_idx);
   gcc_assert (field != NULL_TREE);
 
   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
@@ -376,6 +387,7 @@ gfc_conv_descriptor_elem_len_set (stmtblock_t *block, tree 
desc,
   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
 }
 
+
 static tree
 get_descriptor_type (tree desc)
 {
@@ -403,6 +415,42 @@ gfc_conv_descriptor_type_set (stmtblock_t *block, tree 
desc, tree value)
   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
 }
 
+void
+gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, int value)
+{
+  tree type = TREE_TYPE (desc);
+  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+  tree dtype = get_type_field (type, DTYPE_FIELD);
+  gcc_assert (dtype != NULL_TREE);
+
+  tree field = get_type_field (TREE_TYPE (dtype), GFC_DTYPE_TYPE);
+  gcc_assert (field != NULL_TREE);
+
+  tree type_value = build_int_cst (TREE_TYPE (field), value);
+  gfc_conv_descriptor_type_set (block, desc, type_value);
+}
+
+tree
+gfc_conv_descriptor_type_set (tree desc, tree value)
+{
+  stmtblock_t block;
+
+  gfc_init_block (&block);
+  gfc_conv_descriptor_type_set (&block, desc, value);
+  return gfc_finish_block (&block);
+}
+
+tree
+gfc_conv_descriptor_type_set (tree desc, int value)
+{
+  stmtblock_t block;
+
+  gfc_init_block (&block);
+  gfc_conv_descriptor_type_set (&block, desc, value);
+  return gfc_finish_block (&block);
+}
+
 
 tree
 gfc_get_descriptor_dimension (tree desc)
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 8e5b9583b9af..0547157bf2af 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -74,6 +74,9 @@ void gfc_conv_descriptor_elem_len_set (stmtblock_t *block, 
tree desc, tree value
 void gfc_conv_descriptor_version_set (stmtblock_t *block, tree desc, tree 
value);
 void gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, int value);
+void gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, tree value);
+tree gfc_conv_descriptor_type_set (tree desc, tree value);
+tree gfc_conv_descriptor_type_set (tree desc, int value);
 void gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, tree 
dim, tree value);
 void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, int 
dim, tree value);

Reply via email to