Hello Mikae,

This together with the first part are good to go. I leave it to you as
to when to backport to 16-branch.

Thanks for both the patches.

Regards

Paul


Paul

On Wed, 6 May 2026 at 21:49, Mikael Morin <[email protected]> wrote:
>
> From: Mikael Morin <[email protected]>
>
> With the previous refactoring patch, the fix becomes trivial.
>
> The testcase includes the examples from both PR125192 and PR125198.
> For some reason, the testcase with an unpatched compiler causes a
> segmentation fault when run with the test harness, and the out of bounds
> runtime error as in the PR when executed manually.  As I could reliably
> get a testsuite FAIL that is fixed by the patch, I haven't investigated
> further.  The code generated by the front-end was invalid anyway.
>
> Regression-tested on powerpc64le-unknown-linux-gnu.
> OK for master and 16 backport?
>
> -- >8 --
>
> In gfc_conv_expr_descriptor, the array bounds checking code is added
> to the root block, which is a different block from the scalarizer block
> used to generate the array descriptor reference.  This causes the array
> bounds checking code to come before, which can be problematic if the
> descriptor reference uses variables generated by the scalarizer, as they
> are used in bounds checking code before their definition in that case.
>
> This change adds the bounds checking code to the same block the
> scalarizer uses to generate the array descriptor reference, solving the
> use before definition problem.
>
>         PR fortran/125192
>         PR fortran/125198
>
> gcc/fortran/ChangeLog:
>
>         * trans-array.cc (gfc_conv_expr_descriptor): Add bounds checking
>         code to the outermost loop's preliminary block.
>
> gcc/testsuite/ChangeLog:
>
>         * gfortran.dg/bounds_check_29.f90: New test.
> ---
>  gcc/fortran/trans-array.cc                    |  2 +-
>  gcc/testsuite/gfortran.dg/bounds_check_29.f90 | 62 +++++++++++++++++++
>  2 files changed, 63 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gfortran.dg/bounds_check_29.f90
>
> diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
> index 4f86ae2889b..cb55e5082d4 100644
> --- a/gcc/fortran/trans-array.cc
> +++ b/gcc/fortran/trans-array.cc
> @@ -8652,7 +8652,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
>
>    /* Add bounds-checking for elemental dimensions.  */
>    if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !expr->no_bounds_check)
> -    array_bound_check_elemental (&se->pre, ss, expr);
> +    array_bound_check_elemental (&outermost_loop (&loop)->pre, ss, expr);
>
>    if (need_tmp)
>      {
> diff --git a/gcc/testsuite/gfortran.dg/bounds_check_29.f90 
> b/gcc/testsuite/gfortran.dg/bounds_check_29.f90
> new file mode 100644
> index 00000000000..42ab7afaa47
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/bounds_check_29.f90
> @@ -0,0 +1,62 @@
> +! { dg-do run }
> +! { dg-additional-options "-fcheck=bounds" }
> +!
> +! Check that if an array descriptor reference uses variables, they are
> +! not used uninitialized by the bounds-checking code.
> +
> +
> +! PR fortran/125192
> +! Original example from Philippe Wautelet <philippe.wautelet at cnrs dot fr>
> +
> +subroutine boundcheck_bug
> +  implicit none
> +
> +  type isba_pe_t
> +    real, pointer, dimension(:,:) :: xwg
> +  end type isba_pe_t
> +  type isba_npe_t
> +    type(isba_pe_t), dimension(:), pointer :: al=>null()
> +  end type isba_npe_t
> +  type(isba_npe_t) :: npe
> +
> +  allocate(npe%al(10))
> +  allocate(npe%al(1)%xwg(3,4))
> +
> +  call random_number( npe%al(1)%xwg(:,3) )
> +end subroutine boundcheck_bug
> +
> +
> +! PR fortran/125198
> +! Original example from Neil Carlson <neil.n.carlson at gmail dot com>
> +
> +module unstr_mesh_type
> +  type unstr_mesh
> +    real, allocatable :: normal(:,:)
> +  contains
> +    procedure :: compute_geometry
> +  end type
> +contains
> +  subroutine compute_geometry(this)
> +    class(unstr_mesh), intent(inout) :: this
> +    character(64) :: buf
> +    !print *, this%normal(1,1) ! THIS IS OKAY
> +    write(buf,*) this%normal(1,1)
> +    if (trim(buf) /= '   0.00000000') error stop 1
> +    !print *, this%normal(:,1) ! SPURIOUS BOUNDS ERROR HERE
> +    write(buf,*) this%normal(:,1)
> +    if (trim(buf) /= '   0.00000000       0.00000000       0.00000000') 
> error stop 2
> +    !if (any(this%normal(:,1) /= 0.0)) error stop 2
> +  end subroutine
> +end module
> +
> +subroutine test_pr125198
> +use unstr_mesh_type
> +type(unstr_mesh) :: mesh
> +allocate(mesh%normal(3,10), source=0.0)
> +call mesh%compute_geometry
> +end subroutine
> +
> +
> +call boundcheck_bug
> +call test_pr125198
> +end
> --
> 2.53.0
>

Reply via email to