https://gcc.gnu.org/g:e98dca37b728ab2c1ec16fb12e1010a619b0923a
commit e98dca37b728ab2c1ec16fb12e1010a619b0923a Author: Mikael Morin <[email protected]> Date: Wed May 6 12:25:33 2026 +0200 fortran: Add bound checking code to the scalarizer block [PR125192] In gfc_conv_expr_descriptor, the array bound 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 bound checking code to come before, which can be problematic if the descriptor reference uses variables generated by the scalarizer, as they will be used in bound checking code before their definition. This change adds the bound 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 bound checking code to the outermost loop's preliminary block. gcc/testsuite/ChangeLog: * gfortran.dg/bounds_check_29.f90: New test. Diff: --- gcc/fortran/trans-array.cc | 2 +- gcc/testsuite/gfortran.dg/bounds_check_29.f90 | 62 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 4f86ae2889bc..cb55e5082d4f 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 000000000000..42ab7afaa470 --- /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
