https://gcc.gnu.org/g:f2dd14273480ab0145a7931e1be1bf3cfae0e935
commit f2dd14273480ab0145a7931e1be1bf3cfae0e935 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Tue Sep 23 18:55:08 2025 +0200 Correction régression class_result_10.f90 Diff: --- gcc/fortran/trans-array.cc | 25 ++++++++++++++++++------- gcc/fortran/trans-expr.cc | 4 +++- gcc/fortran/trans.cc | 16 +++++++++------- gcc/fortran/trans.h | 2 +- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index cea098c5a94e..22db090d62d8 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -3641,7 +3641,8 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, static bool -is_class_array_ref (tree base, gfc_expr *expr, tree *class_descr) +is_class_array_ref (gfc_se *se, tree base, gfc_expr *expr, gfc_array_ref *ar, + tree *class_descr) { tree decl = NULL_TREE; tree tmp; @@ -3649,6 +3650,15 @@ is_class_array_ref (tree base, gfc_expr *expr, tree *class_descr) gfc_typespec *ts; gfc_symbol *sym; + if (se->class_container) + { + if (class_descr) + *class_descr = se->class_container; + return true; + } + else if (ar && ar->type == AR_ELEMENT) + return false; + tmp = !VAR_P (base) ? gfc_get_class_from_expr (base) : NULL_TREE; if (tmp != NULL_TREE) @@ -3714,12 +3724,13 @@ give_up: /* Build a scalarized array reference using the vptr 'size'. */ static bool -build_class_array_ref (gfc_se *se, tree base, gfc_expr * expr, tree index) +build_class_array_ref (gfc_se *se, tree base, gfc_expr * expr, + gfc_array_ref *ar, tree index) { tree size; tree decl = NULL_TREE; - if (!is_class_array_ref (base, expr, &decl)) + if (!is_class_array_ref (se, base, expr, ar, &decl)) return false; se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre); @@ -3795,7 +3806,7 @@ enum gfc_array_ref_sort static gfc_array_ref_sort -classify_array_ref (tree array, tree ref_base, gfc_expr *expr, +classify_array_ref (gfc_se *se, tree array, tree ref_base, gfc_expr *expr, gfc_array_ref *ar, bool tmp_array) { if (ar && ar->dimen == 0 && ar->codimen != 0) @@ -3834,7 +3845,7 @@ classify_array_ref (tree array, tree ref_base, gfc_expr *expr, return ARS_CLASS_PTR_ARITH; } } - else if (is_class_array_ref (ref_base, expr, nullptr)) + else if (is_class_array_ref (se, ref_base, expr, ar, nullptr)) return ARS_CLASS_PTR_ARITH; if (tmp_array || non_negative_strides_array_p (array)) @@ -3848,11 +3859,11 @@ static void build_array_ref (gfc_se *se, tree array, tree ref_base, gfc_expr *expr, gfc_array_ref *ar, bool is_temp_array, tree index) { - switch (classify_array_ref (array, ref_base, expr, ar, is_temp_array)) + switch (classify_array_ref (se, array, ref_base, expr, ar, is_temp_array)) { case ARS_CLASS_PTR_ARITH: { - bool success = build_class_array_ref (se, ref_base, expr, index); + bool success = build_class_array_ref (se, ref_base, expr, ar, index); gcc_assert (success); } break; diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index d6130bae5292..c2d5730a9d78 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -671,7 +671,7 @@ gfc_reset_len (stmtblock_t *block, gfc_expr *expr) for expressions other than variables. */ tree -gfc_get_class_from_gfc_expr (gfc_expr *e) +gfc_get_class_from_gfc_expr (gfc_expr *e, stmtblock_t *pre_block) { gfc_expr *class_expr; gfc_se cse; @@ -681,6 +681,8 @@ gfc_get_class_from_gfc_expr (gfc_expr *e) gfc_init_se (&cse, NULL); gfc_conv_expr (&cse, class_expr); gfc_free_expr (class_expr); + if (pre_block) + gfc_add_block_to_block (pre_block, &cse.pre); return cse.expr; } diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 66c0bf28f06b..adb8eea70198 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1422,14 +1422,14 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2, expr->corank = CLASS_DATA (expr2->symtree->n.sym)->as->corank; } - stmtblock_t tmp_block; - gfc_start_block (&tmp_block); - gfc_se final_se; gfc_init_se (&final_se, NULL); get_final_proc_ref (&final_se, expr, class_container); gfc_add_block_to_block (block, &final_se.pre); + stmtblock_t tmp_block; + gfc_start_block (&tmp_block); + gfc_se size_se; gfc_init_se (&size_se, NULL); get_elem_size (&size_se, expr, class_container); @@ -1507,8 +1507,6 @@ gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag) gfc_se se; gfc_symbol *sym = expr1->symtree->n.sym; gfc_ref *ref = expr1->ref; - stmtblock_t final_block; - gfc_init_block (&final_block); gfc_expr *finalize_expr; bool class_array_ref; @@ -1544,6 +1542,8 @@ gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag) if (!gfc_may_be_finalized (sym->ts)) return false; + stmtblock_t outer_block, final_block; + gfc_start_block (&outer_block); gfc_init_block (&final_block); bool finalizable = gfc_add_finalizer_call (&final_block, finalize_expr); gfc_free_expr (finalize_expr); @@ -1558,7 +1558,7 @@ gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag) { if (expr1->ts.type == BT_CLASS) { - ptr = gfc_get_class_from_gfc_expr (expr1); + ptr = gfc_get_class_from_gfc_expr (expr1, &outer_block); gcc_assert (ptr != NULL_TREE); ptr = gfc_class_data_get (ptr); if (lhs_attr.dimension) @@ -1577,6 +1577,7 @@ gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag) gfc_conv_expr (&se, expr1); ptr = gfc_build_addr_expr (NULL_TREE, se.expr); } + gfc_add_block_to_block (&outer_block, &se.pre); } cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, @@ -1597,7 +1598,8 @@ gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag) build_empty_stmt (input_location)); } - gfc_add_expr_to_block (&lse->finalblock, final_expr); + gfc_add_expr_to_block (&outer_block, final_expr); + gfc_add_expr_to_block (&lse->finalblock, gfc_finish_block (&outer_block)); return true; } diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 1cfe8824fecc..3dda2f2ecb96 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -473,7 +473,7 @@ void gfc_reset_vptr (stmtblock_t *, gfc_expr *, tree = NULL_TREE, gfc_symbol * = nullptr); void gfc_class_set_vptr (stmtblock_t *, tree, tree); void gfc_reset_len (stmtblock_t *, gfc_expr *); -tree gfc_get_class_from_gfc_expr (gfc_expr *); +tree gfc_get_class_from_gfc_expr (gfc_expr *, stmtblock_t *pre_block = nullptr); tree gfc_get_class_from_expr (tree); tree gfc_get_vptr_from_expr (tree); tree gfc_copy_class_to_class (tree, tree, tree, bool);