Bug 30802

Summary: out of bounds error array I/O not picked up with -fbounds-check
Product: gcc Reporter: Gareth Vaughan <glv>
Component: fortranAssignee: anlauf
Status: RESOLVED FIXED    
Severity: normal CC: anlauf, anthony.debeus, Edouard.Canot, gcc-bugs, jvdelisle2, P.Schaffnit, tkoenig, vivekrao4
Priority: P3 Keywords: diagnostic
Version: 4.1.1   
Target Milestone: 14.0   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97039
Host: Target:
Build: Known to work:
Known to fail: 4.1.2, 4.2.0, 4.3.0 Last reconfirmed: 2007-05-09 08:09:27
Bug Depends on:    
Bug Blocks: 27766, 37802    

Description Gareth Vaughan 2007-02-15 00:28:39 UTC
Hi All,

For the following code:
program test
real, allocatable :: pos(:,:)
allocate(pos(2,2))
pos = 0.0
print *,pos(5,:)
deallocate(pos)
end program test

when compiled with:
gfortran -fbounds-check test.f95 

the out of bounds array reference in the print command should be picked up, but isn't.  

Also fails in the same way using g95.

Replacing pos(5,:) with pos(5,1) is picked up.

Thanks, Gareth
Comment 1 Tobias Burnus 2007-03-07 07:23:25 UTC
*** Bug 31059 has been marked as a duplicate of this bug. ***
Comment 2 Francois-Xavier Coudert 2007-08-06 21:13:42 UTC
It's not about being allocatable, it's the I/O operation that doesn't perform the necessary check:

$ cat a.f90
  real :: x(2,2)
  x = 0.
  print *, x(5,:)
  x(5,:) = 1.
end
$ gfortran -fbounds-check a.f90 && ./a.out
   0.000000      5.8787666E-39
At line 4 of file a.f90
Fortran runtime error: Array reference out of bounds for array 'x', upper bound of dimension 1  exceeded
Comment 3 Thomas Koenig 2007-12-17 22:23:11 UTC
I think the problem is that we don't insert bounds checking
in gfc_conv_expr_descriptor.

Another test case:

$ cat index.f90 
module bar
contains
  subroutine foo(a)
  real, dimension(:) :: a
  a = 3.
  end subroutine foo
end module bar
program main
  use bar
  real, dimension(2,2) :: a
  n = 3
  call foo(a(n,:))
end program main
$ gfortran index.f90 
$ gfortran -fbounds-check index.f90 
$ ./a.out
Comment 4 Jerry DeLisle 2010-04-18 15:31:38 UTC
Re-confirmed.

We have no bounds checking code in fortran/io.c nor in the I/O library.
Comment 5 Dominique d'Humieres 2015-12-05 21:45:10 UTC
Still present at r231319.
Comment 6 Jerry DeLisle 2015-12-07 21:22:06 UTC
Intentionally not in the library for efficiency. However we can build in some runtime checks with -fcheck=.  This one is on my radar and I was just looking at it a few days ago. Not taking assignment yet.
Comment 7 Dominique d'Humieres 2016-04-05 10:33:43 UTC
*** Bug 52788 has been marked as a duplicate of this bug. ***
Comment 8 markeggleston 2020-01-13 10:51:04 UTC
trunk (10.0 svn revision 280100)

Current state of play:

For arrays allocated at compile time bounds checking works at compile time:

program test
integer, dimension(10,10) :: x
print *, x(0,:)
end program test

$ gfortran -fbounds-check pr30802.f90


    7 | print *, x(0,:)
      |           1
Warning: Array reference at (1) is out of bounds (0 < 1) in dimension 1

Changing to allocated arrays and bounds checking does not work at compile time but does at runtime:

program test
real, allocatable :: x(:)
allocate(x(10))
x = 0.0
print *, x(0)
deallocate(x)
end program test

$ gfortran -fbounds-check pr30802.f90
$ ./a.out

At line 5 of file pr30802.f90
Fortran runtime error: Index '0' of dimension 1 of array 'x' below lower bound of 1

Error termination. Backtrace:
#0  0x400ea1 in ???
#1  0x400f6d in ???
#2  0x4380b2 in ???
#3  0x438471 in ???
#4  0x400c69 in ???
Comment 9 anlauf 2020-10-28 20:27:05 UTC
(In reply to markeggleston from comment #8)
> Changing to allocated arrays and bounds checking does not work at compile
> time but does at runtime:
> 
> program test
> real, allocatable :: x(:)
> allocate(x(10))
> x = 0.0
> print *, x(0)
> deallocate(x)
> end program test
> 
> $ gfortran -fbounds-check pr30802.f90
> $ ./a.out
> 
> At line 5 of file pr30802.f90
> Fortran runtime error: Index '0' of dimension 1 of array 'x' below lower
> bound of 1
> 
> Error termination. Backtrace:
> #0  0x400ea1 in ???
> #1  0x400f6d in ???
> #2  0x4380b2 in ???
> #3  0x438471 in ???
> #4  0x400c69 in ???

I think the point is that bounds-checking does not work for sections of rank-2
arrays.  See also PR97039.

This is not I/O specific, but what Thomas said in comment#3.
Comment 10 anlauf 2023-09-14 19:44:45 UTC
I am working on a patch.
Comment 12 GCC Commits 2023-09-15 17:14:15 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:1cbf18978aa384bd0ed2dc29b107fc3423cf8e62

commit r14-4039-g1cbf18978aa384bd0ed2dc29b107fc3423cf8e62
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Fri Sep 15 19:13:38 2023 +0200

    Fortran: improve bounds-checking for array sections [PR30802]
    
    gcc/fortran/ChangeLog:
    
            PR fortran/30802
            * trans-array.cc (trans_array_bound_check): Add optional argument
            COMPNAME for explicit specification of array component name.
            (array_bound_check_elemental): Helper function for generating
            bounds-checking code for elemental dimensions.
            (gfc_conv_expr_descriptor): Use bounds-checking also for elemental
            dimensions, i.e. those not handled by the scalarizer.
    
    gcc/testsuite/ChangeLog:
    
            PR fortran/30802
            * gfortran.dg/bounds_check_fail_6.f90: New test.
Comment 13 anlauf 2023-09-15 18:21:44 UTC
*** Bug 97039 has been marked as a duplicate of this bug. ***
Comment 14 anlauf 2023-09-15 19:06:03 UTC
Fixed on mainline for gcc-14.
Comment 15 GCC Commits 2024-03-21 17:56:40 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:509352069d6f166d396f4b4a86e71ea521f2ca78

commit r14-9597-g509352069d6f166d396f4b4a86e71ea521f2ca78
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Wed Mar 20 20:59:24 2024 +0100

    Fortran: improve array component description in runtime error message [PR30802]
    
    Runtime error messages for array bounds violation shall use the following
    scheme for a coherent, abridged description of arrays or array components
    of derived types:
    (1) If x is an ordinary array variable, use "x"
    (2) if z is a DT scalar and x an array component at level 1, use "z%x"
    (3) if z is a DT scalar and x an array component at level > 1, or
        if z is a DT array and x an array (at any level), use "z...%x"
    Use a new helper function abridged_ref_name for construction of that name.
    
    gcc/fortran/ChangeLog:
    
            PR fortran/30802
            * trans-array.cc (abridged_ref_name): New helper function.
            (trans_array_bound_check): Use it.
            (array_bound_check_elemental): Likewise.
            (gfc_conv_array_ref): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            PR fortran/30802
            * gfortran.dg/bounds_check_17.f90: Adjust pattern.
            * gfortran.dg/bounds_check_fail_8.f90: New test.