6
votes

I have found a bug in a large program where a subroutine was written as:

program main
  implicit none

  real, dimension(6) :: x
  call f(x, 7)
  write (*,*) x
contains
  subroutine f(x, n)
    integer :: n
    real, dimension(n) :: x

    integer :: i

    do i = 1, n
      x(i) = 0.0
    end do
  end subroutine f
end program main

This program runs fine with both ifort and gfortran and bounds checking even though the code is obviously buggy. Is there an option to catch those kind of bugs?

PS: Here are the two commands that generate binaries that run fine

  • ifort -check all main.f90 -o main
  • gfortran -fbounds-check main.f90 -o main
2
@francescalus: I have precised the question with a real code. - InsideLoop
I'm not aware of suitable options for gfortran/ifort, but I do know of options for other compilers. Would that option/compiler be useful for you? - francescalus
What compiler do you have options for? - InsideLoop
Unfortunately, I don't have access to a Nag compiler - InsideLoop
@InsideLoop please consider reporting this bug to Intel Fortran and GFortran teams: software.intel.com/en-us/support/priority-support - King

2 Answers

2
votes

Disclaimer: The author ask for an option to catch the bug. This answer doesn't provide it.


If the array is an assumed shaped (dimension(:)), the check is performed:

ifort 15.5

forrtl: severe (408): fort: (2): Subscript #1 of the array X has value 7 which is greater than the upper bound of 6

gfortran 6.1.0

Fortran runtime error: Index '7' of dimension 1 of array 'x' above upper bound of 6

whereas when its and assumed size (dimension(*)) or explicited shape (dimension(n)) it is not. It may be purposely designed.

ifort manual

Array bounds checking is not performed for arrays that are dummy arguments in which the last dimension bound is specified as * or when both upper and lower dimensions are 1.

gfortran manual dosn't detail that point

2
votes

This is an important class of programming error where compilers are not too great when it comes to detecting instances. As the question notes, both the Intel and GNU compilers fail to detect a problem when compiling with array access bounds checking.

Indeed, I am not aware of other flags which turn on such checking in the compiler at run-time.

However, in some cases both gfortran and ifort can catch the error. When the actual or argument has an explicit size given by a constant expression and the interface of the subroutine is "known" (not necessarily explicit) the error may be detected. With gfortran, the procedure being in the same file may enable this checking and with ifort the option -warn interfaces (maybe after -gen_interfaces) does the same.

Now, this as this is an important class of error we can go beyond the simple limits of the question. As the answer by PTRK says, the error can be mitigated by not using explicit shape dummies.

Additionally, the NAG compiler, as one example, does offer such run-time checks for actual arguments being no shorter than associated dummy arguments. Compiled with -C the code of the question gives the run-time error:

line 8: Invalid reference to procedure MAIN:F - Dummy array X (number 1) has 7 elements but actual argument only has 6 elements
Program terminated by fatal error

It is always worth considering a variety of tools to catch different aspects of potential programming errors or unwise practices.