NVFortran: closures does not work


The following program (that consists of 2 files) is SegFaulted at runtime if compiled with NVFortran 24.3:

==> closure.f <==
      program main
        call eval('asdf', 5)
      end program main
      subroutine eval(path, val)
        character(len=4) :: path
        integer :: val
        call run(closure)
        subroutine closure()
          if (path == 'asdf') then
            print *, val
            print *, -val
          end if
        end subroutine closure
      end subroutine eval

==> run.f <==
      subroutine run(f)
        external f
        call f
      end subroutine run

Compilation & run:

$ nvfortran run.f closure.f -O0 && ./a.out
Segmentation fault (core dumped)

gdb output:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffed4c6880 in pgf90_strcmp_klen () from .../compilers/nvidia/24.3/Linux_x86_64/24.3/compilers/lib/libnvf.so
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-225.el8.x86_64
(gdb) bt
#0  0x00007fffed4c6880 in pgf90_strcmp_klen () from .../compilers/nvidia/24.3/Linux_x86_64/24.3/compilers/lib/libnvf.so
#1  0x00007fffffff5c18 in ?? ()
#2  0x0000000000401100 in ?? ()
#3  0x00007fffffff5c10 in ?? ()
#4  0x0000000000000000 in ?? ()

It works properly if the whole code is in single file (at least for example).

gfortran (12.2), ifort (2021.12.0), ifx (2024.1.0) produces a proper answer, however for them linker says:

ld: warning: /tmp/ccc0StcN.o: requires executable stack (because the .note.GNU-stack section is executable)

Hi foxtranigor,

This is known limitation in nvfortran (See bullet 3)

  • Passing an internal procedure as an actual argument to a Fortran subprogram is supported by nvfortran provided that the dummy argument is declared as an interface block or as a procedure dummy argument. nvfortran does not support internal procedures as actual arguments to dummy arguments declared external.

The code will work if you add an interface block. Something like:

      subroutine run(f)
!        external f
      subroutine f()
      end subroutine
      end interface
        call f
      end subroutine run

Hope this helps,

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.