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

Reply via email to