Fortran type bound function returning short integer fails

Hello,

we are trying to compile some Fortran libraries and we encounter some errors. We extracted the following minimal reproducing example which fails using nvfortran 20.7.

program test
type :: a_object
contains
procedure :: to_integer_I2P
endtype a_object

integer, parameter :: I2P=selected_int_kind(4)
type(a_object) :: object

print*, object%to_integer_I2P()
contains
function to_integer_I2P(self) result(n) ! it does not work
class(a_object) :: self
integer(I2P) :: n
endfunction to_integer_I2P
endprogram test

Thanks
Francesco

The code doesn’t seem valid (at least it errors with ifort and gfortran). Is the issue that nvfortran isn’t catching the errors as well? I can submit a problem report, but given this is from a larger, presumably correct, code, I want to make sure our engineers are fixing the correct issue.

    % ifort --version
    ifort (IFORT) 19.1.1.217 20200306
    Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

     % ifort test.f90
    test.f90(4): error #8258: The procedure name in a type-bound procedure declaration should be the name of an accessible module procedure or an external procedure that has an explicit interface.   [TO_INTEGER_I2P]
    procedure :: to_integer_I2P
    -------------^
    test.f90(10): error #8607: The procedure interface for the type bound procedure is not yet available.   [TO_INTEGER_I2P]
    print*, object%to_integer_I2P()
    ---------------^
    test.f90(10): error #8497: Illegal use of a procedure name in an expression, possibly a function call missing parenthesis.   [TO_INTEGER_I2P]
    print*, object%to_integer_I2P()
    ---------------^
    test.f90(12): warning #6178: The return value of this FUNCTION has not been defined.   [N]
    function to_integer_I2P(self) result(n) ! it does not work
    -------------------------------------^
    compilation aborted for test.f90 (code 1)
    % gfortran --version
    GNU Fortran (GCC) 9.2.0
    Copyright (C) 2019 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    % gfortran test.f90
    test.f90:4:9:

        4 | procedure :: to_integer_I2P
          |         1
    Error: ‘to_integer_i2p’ must be a module procedure or an external procedure with an explicit interface at (1)
    test.f90:10:7:

   10 | print*, object%to_integer_I2P()
  |       1
Error: ‘to_integer_i2p’ at (1) should be a FUNCTION

Sorry, we reduced the code too much. However, including explicit interfaces using a module:

module test
type :: a_object
contains
procedure :: to_integer_I2P
endtype a_object

! integer, parameter :: I2P=selected_int_kind(9) ! this works
integer, parameter :: I2P=selected_int_kind(4) ! this does not work

contains
function to_integer_I2P(self) result(n)
class(a_object) :: self
integer(I2P) :: n
endfunction to_integer_I2P
endmodule test

we still have the following error using nvfortran x86 compiler (ppc64 nvfortran compiler works, gfortran works):

/opt/nvidia/hpc_sdk/Linux_x86_64/20.7/compilers/share/llvm/bin/llc: error: /opt/nvidia/hpc_sdk/Linux_x86_64/20.7/compilers/share/llvm/bin/llc: /tmp/nvfortranCeXdu9xI6Tl-.ll:8:67: error: invalid forward reference to function ‘test_to_integer_i2p_’ with wrong type: expected ‘i32 (i64*, i64*)’ but was 'i32 ()
@test$a_object$$td$vft = global [1 x i8*] [i8* bitcast(i32 ()* @test_to_integer_i2p_ to i8*)]

Francesco

Thanks Francesco, we appreciate that. I added a new problem report (TPR#29177) for the LLVM code generation issue. I also went ahead and added TPR#29118 to see if we can catch the errors in the earlier code as well.

-Mat