https://gcc.gnu.org/g:6696b3e5358efba567fc8f64c150f154e51ebdec
commit 6696b3e5358efba567fc8f64c150f154e51ebdec Author: Mikael Morin <mik...@gcc.gnu.org> Date: Tue Apr 29 18:40:50 2025 +0200 Restauration intrinsic stride (correction régression finalize_17) Diff: --- gcc/fortran/class.cc | 43 +++++++++++++++++++++++------------------- gcc/fortran/intrinsic.cc | 8 ++++++++ gcc/fortran/trans-intrinsic.cc | 32 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc index 23d8701ac44f..e92760db51dd 100644 --- a/gcc/fortran/class.cc +++ b/gcc/fortran/class.cc @@ -1343,14 +1343,12 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr, offset = 0 do idx2 = 1, rank offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2) - end do - offset = offset * byte_stride. */ + end do */ static gfc_code* finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, gfc_symbol *strides, gfc_symbol *sizes, - gfc_symbol *byte_stride, gfc_expr *rank, - gfc_code *block, gfc_namespace *sub_ns) + gfc_expr *rank, gfc_code *block, gfc_namespace *sub_ns) { gfc_iterator *iter; gfc_expr *expr, *expr2; @@ -1443,17 +1441,6 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, block->block->next->expr2->ts = idx->ts; block->block->next->expr2->where = gfc_current_locus; - /* After the loop: offset = offset * byte_stride. */ - block->next = gfc_get_code (EXEC_ASSIGN); - block = block->next; - block->expr1 = gfc_lval_expr_from_sym (offset); - block->expr2 = gfc_get_expr (); - block->expr2->expr_type = EXPR_OP; - block->expr2->value.op.op = INTRINSIC_TIMES; - block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset); - block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride); - block->expr2->ts = block->expr2->value.op.op1->ts; - block->expr2->where = gfc_current_locus; return block; } @@ -1926,10 +1913,29 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns, last_code->ext.iterator = iter; last_code->block = gfc_get_code (EXEC_DO); - /* sizes(idx) = ... */ + /* strides(idx) = _F._stride(array,dim=idx). */ last_code->block->next = gfc_get_code (EXEC_ASSIGN); block = last_code->block->next; + block->expr1 = gfc_lval_expr_from_sym (strides); + block->expr1->ref = gfc_get_ref (); + block->expr1->ref->type = REF_ARRAY; + block->expr1->ref->u.ar.type = AR_ELEMENT; + block->expr1->ref->u.ar.dimen = 1; + block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; + block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx); + block->expr1->ref->u.ar.as = strides->as; + + block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride", + gfc_current_locus, 2, + gfc_lval_expr_from_sym (array), + gfc_lval_expr_from_sym (idx)); + + /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */ + block->next = gfc_get_code (EXEC_ASSIGN); + block = block->next; + + /* sizes(idx) = ... */ block->expr1 = gfc_lval_expr_from_sym (sizes); block->expr1->ref = gfc_get_ref (); block->expr1->ref->type = REF_ARRAY; @@ -2146,8 +2152,7 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns, /* Offset calculation. */ block = finalization_get_offset (idx, idx2, offset, strides, sizes, - byte_stride, rank, block->block, - sub_ns); + rank, block->block, sub_ns); /* Create code for CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr) @@ -2217,7 +2222,7 @@ finish_assumed_rank: /* Offset calculation. */ block = finalization_get_offset (idx, idx2, offset, strides, sizes, - byte_stride, rank, last_code->block, + rank, last_code->block, sub_ns); /* Create code for diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc index 417d285ec308..30f532b5766b 100644 --- a/gcc/fortran/intrinsic.cc +++ b/gcc/fortran/intrinsic.cc @@ -3125,6 +3125,14 @@ add_functions (void) make_generic ("size", GFC_ISYM_SIZE, GFC_STD_F95); + /* Obtain the stride for a given dimensions; to be used only internally. + "make_from_module" makes it inaccessible for external users. */ + add_sym_2 (GFC_PREFIX ("stride"), GFC_ISYM_STRIDE, CLASS_INQUIRY, ACTUAL_NO, + BT_INTEGER, gfc_index_integer_kind, GFC_STD_GNU, + NULL, NULL, gfc_resolve_stride, + ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL); + make_from_module(); + add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, ii, GFC_STD_GNU, gfc_check_sizeof, gfc_simplify_sizeof, NULL, diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 43e3ebff3bee..12a317440cff 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -2745,6 +2745,34 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr) } +static void +conv_intrinsic_stride (gfc_se * se, gfc_expr * expr) +{ + gfc_actual_arglist *array_arg; + gfc_actual_arglist *dim_arg; + gfc_se argse; + tree desc, tmp; + + array_arg = expr->value.function.actual; + dim_arg = array_arg->next; + + gcc_assert (array_arg->expr->expr_type == EXPR_VARIABLE); + + gfc_init_se (&argse, NULL); + gfc_conv_expr_descriptor (&argse, array_arg->expr); + gfc_add_block_to_block (&se->pre, &argse.pre); + gfc_add_block_to_block (&se->post, &argse.post); + desc = argse.expr; + + gcc_assert (dim_arg->expr); + gfc_init_se (&argse, NULL); + gfc_conv_expr_type (&argse, dim_arg->expr, gfc_array_index_type); + gfc_add_block_to_block (&se->pre, &argse.pre); + tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, + argse.expr, gfc_index_one_node); + se->expr = gfc_conv_descriptor_spacing_get (desc, tmp); +} + static void gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr) { @@ -11272,6 +11300,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr) gfc_conv_intrinsic_spacing (se, expr); break; + case GFC_ISYM_STRIDE: + conv_intrinsic_stride (se, expr); + break; + case GFC_ISYM_SUM: gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false); break;