https://gcc.gnu.org/g:6589f31a914e75161c0e098ec3e129d9b8c6011a

commit r16-8907-g6589f31a914e75161c0e098ec3e129d9b8c6011a
Author: Mikael Morin <[email protected]>
Date:   Thu May 7 20:48:26 2026 +0200

    fortran: Add bounds checking code to the scalarizer block [PR125192]
    
    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.
    
    (cherry picked from commit 0c0c58310180b75a4ff23044006f7ddabe7f894c)

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