https://gcc.gnu.org/g:f58af2eecc319030c685e56c31c14877e15e3b16
commit f58af2eecc319030c685e56c31c14877e15e3b16 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed May 28 18:56:02 2025 +0200 Correction régressions array_reference_3 Diff: --- gcc/fortran/trans-array.cc | 82 +++++++++++++++++-------- gcc/testsuite/gfortran.dg/array_reference_3.f90 | 4 +- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 0109f135cfbe..127cc0cd0951 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -3590,6 +3590,59 @@ build_array_ref (tree array, tree offset, bool use_array_ref) } +static bool +array_section_parent_ref_is_contiguous (gfc_expr *expr, gfc_array_ref *ar) +{ + if (expr == nullptr || ar == nullptr) + return false; + + gfc_symbol *root_sym = expr->symtree->n.sym; + bt last_type = root_sym->ts.type; + bool last_is_allocatable = root_sym->attr.allocatable; + bool last_is_contiguous = root_sym->attr.contiguous; + for (gfc_ref *ref = expr->ref; ref; ref = ref->next) + { + if (ref->type == REF_ARRAY && &ref->u.ar == ar) + break; + + if (ref->type != REF_COMPONENT) + continue; + + if (last_type == BT_CLASS + && strcmp (ref->u.c.component->name, "_data") == 0) + continue; + + last_type = ref->u.c.component->ts.type; + last_is_allocatable = ref->u.c.component->attr.allocatable; + last_is_contiguous = ref->u.c.component->attr.contiguous; + } + + if (!(last_type == BT_CLASS || last_type == BT_CHARACTER) + && (last_is_allocatable || last_is_contiguous)) + return true; + + return false; +} + + +static bool +array_section_parent_ref_is_contiguous (gfc_expr *expr, gfc_ref *array_ref) +{ + if (array_ref == nullptr) + return false; + + return array_section_parent_ref_is_contiguous (expr, &array_ref->u.ar); +} + + +static bool +array_section_parent_ref_is_contiguous (gfc_ss *ss) +{ + return array_section_parent_ref_is_contiguous (ss->info->expr, + ss->info->data.array.ref); +} + + tree build_array_ref_dim (gfc_ss *ss, tree index, tree lbound, tree spacing, bool tmp_array = false) @@ -3603,6 +3656,8 @@ build_array_ref_dim (gfc_ss *ss, tree index, tree lbound, tree spacing, || ss_type == GFC_SS_CONSTRUCTOR || ss_type == GFC_SS_INTRINSIC || tmp_array + || (ss_type == GFC_SS_SECTION + && array_section_parent_ref_is_contiguous (ss)) || non_negative_strides_array_p (info->descriptor); return gfc_build_array_ref (base, index, non_negative_stride, lbound, spacing); @@ -3667,9 +3722,6 @@ add_to_offset (tree *cst_offset, tree *offset, tree t) bool array_ref_safe_p (gfc_expr *expr, gfc_array_ref *ar, tree array, tree *elt_size) { - if (!non_negative_strides_array_p (array)) - return false; - STRIP_NOPS (array); if (TREE_CODE (array) == COMPONENT_REF) { @@ -3682,29 +3734,9 @@ array_ref_safe_p (gfc_expr *expr, gfc_array_ref *ar, tree array, tree *elt_size) return false; } - gfc_symbol *root_sym = expr->symtree->n.sym; - bt last_type = root_sym->ts.type; - bool last_is_allocatable = root_sym->attr.allocatable; - for (gfc_ref *ref = expr->ref; ref; ref = ref->next) - { - if (ref->type == REF_ARRAY && &ref->u.ar == ar) - break; - - if (ref->type != REF_COMPONENT) - continue; - - if (last_type == BT_CLASS - && strcmp (ref->u.c.component->name, "_data") == 0) - continue; - - last_type = ref->u.c.component->ts.type; - last_is_allocatable = ref->u.c.component->attr.allocatable; - } - - if (!(last_type == BT_CLASS || last_type == BT_CHARACTER) - && last_is_allocatable) + if (array_section_parent_ref_is_contiguous (expr, ar)) ; - else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))) + else if (!non_negative_strides_array_p (array)) return false; tree elt_type = gfc_get_element_type (TREE_TYPE (array)); diff --git a/gcc/testsuite/gfortran.dg/array_reference_3.f90 b/gcc/testsuite/gfortran.dg/array_reference_3.f90 index e1e2f0f9afa1..a7a5c03561a9 100644 --- a/gcc/testsuite/gfortran.dg/array_reference_3.f90 +++ b/gcc/testsuite/gfortran.dg/array_reference_3.f90 @@ -178,7 +178,7 @@ contains call casces(x) if (any(x /= (/ 0, 0, 0, 24, 0, 0, 0, 0 /))) stop 24 ! Contiguous assumed shape arrays are referenced with array indexing. - ! { dg-final { scan-tree-dump-times "\\(\\*assumed_shape_cont_x.\\d+\\)\\\[stride.\\d+ \\* 4 \\+ offset.\\d+\\\] = 24;" 1 "original" } } + ! { dg-final { scan-tree-dump-times {\(\*assumed_shape_cont_x.\d+\)\[offset.\d+ /\[ex\] 4 \+ spacing\.\d+\](?:{lb: 0 sz: 4})? = 24;} 1 "original" } } end subroutine check_assumed_shape_cont_elem subroutine cascss(assumed_shape_cont_y) integer, dimension(:), contiguous :: assumed_shape_cont_y @@ -189,7 +189,7 @@ contains call cascss(y) if (any(y /= 25)) stop 25 ! Contiguous assumed shape arrays are referenced with array indexing. - ! { dg-final { scan-tree-dump-times "\\(\\*assumed_shape_cont_y.\\d+\\)\\\[S.\\d+ \\* D.\\d+ \\+ D.\\d+\\\] = 25;" 1 "original" } } + ! { dg-final { scan-tree-dump-times {\(\*assumed_shape_cont_y.\d+\)\[S.\d+\](?:{lb: [01] sz: (?:\(sizetype\) )?D\.\d+})? = 25;} 1 "original" } } end subroutine check_assumed_shape_cont_scalarized end program p