Bug in nvfortran 22.3: false positive of out-bound subscripts

This is a bug that affects all flang-based compilers: NVIDIA nvfortran 22.3 (tested on Ubuntu 20.04), classic flang 7.0.1, Huawei Bisheng flang 1.3.3, and AOCC 3.2.0 flang. They raise a false positive error of out-bound subscripts when invoked with the -Mbounds flag.

Here is a minimal working example. The latest version of the code is available at my GitHub repo dedicated to testing Fortran compilers.

! test_solve.f90
module solve_mod
implicit none
private
public :: solve


contains


function solve(A, b) result(x)  ! A naive solver for upper-triangle linear systems
implicit none
real, intent(in) :: A(:, :), b(:)
real :: x(size(A, 2))
integer :: i, n

n = size(b) 

do i = n, 1, -1
    x(i) = (b(i) - inprod(A(i, i + 1:n), x(i + 1:n))) / A(i, i)
    !x(i) = (b(i) - dot_product(A(i, i + 1:n), x(i + 1:n))) / A(i, i)  ! No problem will arise
end do

end function solve


function inprod(x, y) result(z)
real, intent(in) :: x(:), y(:)
real :: z
z = dot_product(x, y)
end function inprod

end module solve_mod


program test_solve
use, non_intrinsic :: solve_mod, only : solve
implicit none

real :: A(1, 1), b(1)

A = 1.0
b = 1.0

write (*, *) solve(A, b)

end program test_solve

The error message looks like the following.

$ nvfortran -Mbounds test_solve.f90  && ./a.out 
0: Subscript out of range for array x (test_solve.f90: 19)
    subscript=2, lower bound=1, upper bound=1, dimension=1

Thank you for having a look at it.

Hi zaikunzhang,

Isn’t the message correct given the “size(A,2)” is 1, “n” is 1 on the first iteration, and “i+1” would be 2 which is out of bounds when accessing x?

I assume it’s not getting detected when calling dot_product is because it’s using an F77 style calling conventions so passing a pointer and not able to check the bounds.

-Mat

1 Like

Hi @MatColgrove , thank you for the response!

When i = n = 1, the Fortran standard says that A(i, i + 1:n) and x(i + 1:n) are valid and they should be empty arrays. So this is a false positive.

Note that the false positive occurs only if we invoke the compiler with -Mbounds.

For your reference, see what I reported before in “Bug of nvfortran 22.2-0: array subscript triplet handled wrongly”, in case they are related.

(Thank you very much for pointing out the interesting difference between calling dot_product and the wrapped inprod, which I did not know.)

Thanks.

I asked engineering and they agree with you, but noted that this has the same root cause as TPR #31488 which you reported a few weeks ago: Bug of nvfortran 22.2-0: array subscript triplet handled wrongly

I’ll update TPR 31488 with this source.

1 Like

Hi @MatColgrove, thank you for the update!

In case it is helpful, I hope to mention a slight difference between the problem here and the one in Bug of nvfortran 22.2-0: array subscript triplet handled wrongly. For the test_empty.f90 reported two weeks ago, the error can only be triggered by nvfortran -C -O3, not by nvfortran -Mbounds:

$ nvfortran -Mbounds test_empty.f90 && ./a.out
            1            2            3

$ nvfortran -C -O3 test_empty.f90 && ./a.out
0: Subscript out of range for array a (test_empty.f90: 21)
    subscript=4, lower bound=1, upper bound=3, dimension=2

However, for the test_solve.f90 here, it can be triggered by both of them, and also by nvfortran -C:

nvfortran -Mbounds test_solve.f90 && ./a.out
0: Subscript out of range for array x (test_solve.f90: 19)
    subscript=2, lower bound=1, upper bound=1, dimension=1

nvfortran -C test_solve.f90 && ./a.out
0: Subscript out of range for array x (test_solve.f90: 19)
    subscript=2, lower bound=1, upper bound=1, dimension=1

From engineering’s initial triage, while not exactly the same, they believe it’s the same root cause so ask that I combine the two issues.

1 Like

This bug still exists in nvfortran 22.5.

Yes, their original assessment that this was the same issue as TPR #31488 was incorrect. Hence they opened a new report to track: TPR #31733