https://gcc.gnu.org/g:a2d4153bb2a5235ee1ac2d1b68bb7d4afd174451
commit a2d4153bb2a5235ee1ac2d1b68bb7d4afd174451 Author: Mikael Morin <[email protected]> Date: Sun Jun 29 14:11:50 2025 +0200 fortran: array descriptor: Add accessors for the type field [PR122521] Regression tested on aarch64-unknown-linux-gnu. OK for master? -- >8 -- Add accessor functions to get or set the value of the type field of array descriptors, and remove from the public API the function giving direct acces to the field. PR fortran/122521 gcc/fortran/ChangeLog: * trans-descriptor.cc (get_type_field): New function. (gfc_get_descriptor_field): Use it. (gfc_conv_descriptor_type): Make static and rename ... (conv_descriptor_type): ... to this. (gfc_conv_descriptor_type_get, gfc_conv_descriptor_type_set): New functions. * trans-descriptor.h (gfc_conv_descriptor_type): Remove declaration. (gfc_conv_descriptor_type_get, gfc_conv_descriptor_type_set): New declarations. * trans-expr.cc (gfc_conv_gfc_desc_to_cfi_desc): Use gfc_conv_descriptor_type_get to get the value of the type field. * trans-decl.cc (gfc_conv_cfi_to_gfc): Use gfc_conv_descriptor_type_set to set the value of the type field. Diff: --- gcc/fortran/trans-decl.cc | 23 ++++------- gcc/fortran/trans-descriptor.cc | 89 +++++++++++++++++++++++++++++++++++++++-- gcc/fortran/trans-descriptor.h | 6 ++- gcc/fortran/trans-expr.cc | 2 +- 4 files changed, 98 insertions(+), 22 deletions(-) diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 09bffa397180..fab4873b92c4 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -7526,25 +7526,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 (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 > */ @@ -7553,8 +7548,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 > */ @@ -7566,16 +7560,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) @@ -7593,8 +7585,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 2cdeb20b0493..163916bfc275 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -61,14 +61,28 @@ along with GCC; see the file COPYING3. If not see #define LBOUND_SUBFIELD 1 #define UBOUND_SUBFIELD 2 + +/* Get FIELD_IDX'th field in struct TYPE. */ + +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; +} + + +/* Return a reference to the FIELD_IDX-th field of the descriptor DESC. */ + 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); - gcc_assert (field != NULL_TREE); + tree field = get_type_field (type, field_idx); return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE); @@ -295,8 +309,12 @@ gfc_conv_descriptor_attribute (tree desc) dtype, tmp, NULL_TREE); } -tree -gfc_conv_descriptor_type (tree desc) + +/* Return a reference to the type discriminator field of the array descriptor + DESC. */ + +static tree +conv_descriptor_type (tree desc) { tree tmp; tree dtype; @@ -309,6 +327,69 @@ gfc_conv_descriptor_type (tree desc) dtype, tmp, NULL_TREE); } +/* Return the type discriminator value of the array descriptor DESC. */ + +tree +gfc_conv_descriptor_type_get (tree desc) +{ + return conv_descriptor_type (desc); +} + +/* Add code to BLOCK assigning VALUE to the type discriminator field of the + array descriptor DESC. */ + +void +gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, tree value) +{ + location_t loc = input_location; + tree t = conv_descriptor_type (desc); + gfc_add_modify_loc (loc, block, t, + fold_convert_loc (loc, TREE_TYPE (t), value)); +} + +/* Add code to BLOCK assigning VALUE to the type discriminator field of the + array descriptor DESC. */ + +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); + tree field = get_type_field (TREE_TYPE (dtype), GFC_DTYPE_TYPE); + tree type_value = build_int_cst (TREE_TYPE (field), value); + + gfc_conv_descriptor_type_set (block, desc, type_value); +} + +/* Return a statement assigning VALUE to the type discriminator field of the + array descriptor DESC. */ + +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); +} + +/* Return a statement assigning VALUE to the type discriminator field of the + array descriptor DESC. */ + +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 cdf2295abe47..e59ed8ed7b55 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see tree gfc_conv_descriptor_dtype (tree); tree gfc_conv_descriptor_attribute (tree); -tree gfc_conv_descriptor_type (tree); tree gfc_get_descriptor_dimension (tree); tree gfc_conv_descriptor_dimension (tree, tree); tree gfc_conv_descriptor_token (tree); @@ -32,6 +31,7 @@ tree gfc_conv_descriptor_offset_get (tree); tree gfc_conv_descriptor_elem_len_get (tree); tree gfc_conv_descriptor_version_get (tree); tree gfc_conv_descriptor_rank_get (tree); +tree gfc_conv_descriptor_type_get (tree); tree gfc_conv_descriptor_span_get (tree); tree gfc_conv_descriptor_stride_get (tree, tree); @@ -44,6 +44,10 @@ void gfc_conv_descriptor_elem_len_set (stmtblock_t *, tree, tree); void gfc_conv_descriptor_version_set (stmtblock_t *, tree, tree); void gfc_conv_descriptor_rank_set (stmtblock_t *, tree, tree); void gfc_conv_descriptor_rank_set (stmtblock_t *, tree, int); +void gfc_conv_descriptor_type_set (stmtblock_t *, tree, tree); +void gfc_conv_descriptor_type_set (stmtblock_t *, tree, int); +tree gfc_conv_descriptor_type_set (tree, tree); +tree gfc_conv_descriptor_type_set (tree, int); void gfc_conv_descriptor_span_set (stmtblock_t *, tree, tree); void gfc_conv_descriptor_stride_set (stmtblock_t *, tree, tree, tree); void gfc_conv_descriptor_lbound_set (stmtblock_t *, tree, tree, tree); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index c98ca9d2173f..30bc45596810 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6422,7 +6422,7 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym) tree cond; tree ctype = gfc_get_cfi_desc_type (cfi); tree type = fold_convert (TREE_TYPE (ctype), - gfc_conv_descriptor_type (gfc)); + gfc_conv_descriptor_type_get (gfc)); tree kind = fold_convert (TREE_TYPE (ctype), gfc_conv_descriptor_elem_len_get (gfc)); kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
