Fortran 中的 PGI 编译错误:"forward reference to function"
PGI compilation error in Fortran: "forward reference to function"
我对 PGI Fortran 编译器有点疑惑。
当我尝试使用 pgfortran 19.10 编译存储在名为 test.f90
的文件中的以下简单模块时,出现我无法理解的错误。使用 gfortran 或 ifort 编译时 运行 很好。
文件test.f90
:
MODULE CT
IMPLICIT NONE
integer, parameter :: si = SELECTED_INT_KIND(4)
integer(kind=si), public, parameter :: strlen = 256
type, public :: CMT
integer (kind=si) :: nbTot
character(len=strlen), dimension(:), allocatable :: condi
CONTAINS
procedure :: find_line_condi
endtype CMT
CONTAINS
PURE function find_line_condi( table, cara ) result(k)
IMPLICIT NONE
class(CMT), intent(in) :: table
character(len=*), intent(in) :: cara
integer (kind=si) :: k
integer (kind=si) :: j
k=-1
do j=1,table%nbTot
if (trim(table%condi(j)) .eq. cara) then
k=j
RETURN
else if ( j == table%nbTot ) then
k=-1
RETURN
endif
enddo
end function find_line_condi
END MODULE CT
用pgfortran -c test.f90
编译returns我报错如下:
/opt/pgi/linux86-64-llvm/19.10/share/llvm/bin/llc: error: /opt/pgi/linux86-64-llvm/19.10/share/llvm/bin/llc: /tmp/pgfortranr2qeZBujkwvA.ll:23:77: error: invalid forward reference to function 'ct_find_line_condi_' with wrong type: expected 'i32 (i64*, i64*, i64*, i64)*' but was 'i16 (i64*, i64*, i64*, i64)*'
@ct$cmt$td$vft = global [1 x i8*] [i8* bitcast(i16 (i64*, i64*, i64*, i64)* @ct_find_line_condi_ to i8*)]
有人知道这个问题是从哪里来的吗?
这是编译器中的错误。考虑模块
MODULE CT
IMPLICIT NONE
type CMT
CONTAINS
procedure, nopass :: find_line_condi
endtype CMT
CONTAINS
function find_line_condi()
integer(SELECTED_INT_KIND(4)) find_line_condi
find_line_condi=0
end function find_line_condi
END MODULE CT
比那个问题简单多了。使用 pgfortran 19.10 编译有类似的乱码输出。这个更简单的代码是否是有效的 Fortran 代码留给 reader/PGI 支持台作为练习,它应该被接受,但我认为糟糕的诊断是 PGI 希望避免的事情。
然而,这似乎是 PGI 的 LLVM 前端的一个弱点:考虑使用 pgfortran -c -Mnollvm ...
进行编译。还有一些方法可以重写代码以尝试解决此错误,例如更改函数结果的类型。
更广泛地说,PGI introduced in the 2019 releases the LLVM code generator. This seems to be going through a number of teething difficulties。如果您的代码在 PGI 2019 中意外失败(可能在 2018 中有效),那么使用 -Mnollvm
编译以使用非 LLVM 生成器值得一试。
我对 PGI Fortran 编译器有点疑惑。
当我尝试使用 pgfortran 19.10 编译存储在名为 test.f90
的文件中的以下简单模块时,出现我无法理解的错误。使用 gfortran 或 ifort 编译时 运行 很好。
文件test.f90
:
MODULE CT
IMPLICIT NONE
integer, parameter :: si = SELECTED_INT_KIND(4)
integer(kind=si), public, parameter :: strlen = 256
type, public :: CMT
integer (kind=si) :: nbTot
character(len=strlen), dimension(:), allocatable :: condi
CONTAINS
procedure :: find_line_condi
endtype CMT
CONTAINS
PURE function find_line_condi( table, cara ) result(k)
IMPLICIT NONE
class(CMT), intent(in) :: table
character(len=*), intent(in) :: cara
integer (kind=si) :: k
integer (kind=si) :: j
k=-1
do j=1,table%nbTot
if (trim(table%condi(j)) .eq. cara) then
k=j
RETURN
else if ( j == table%nbTot ) then
k=-1
RETURN
endif
enddo
end function find_line_condi
END MODULE CT
用pgfortran -c test.f90
编译returns我报错如下:
/opt/pgi/linux86-64-llvm/19.10/share/llvm/bin/llc: error: /opt/pgi/linux86-64-llvm/19.10/share/llvm/bin/llc: /tmp/pgfortranr2qeZBujkwvA.ll:23:77: error: invalid forward reference to function 'ct_find_line_condi_' with wrong type: expected 'i32 (i64*, i64*, i64*, i64)*' but was 'i16 (i64*, i64*, i64*, i64)*'
@ct$cmt$td$vft = global [1 x i8*] [i8* bitcast(i16 (i64*, i64*, i64*, i64)* @ct_find_line_condi_ to i8*)]
有人知道这个问题是从哪里来的吗?
这是编译器中的错误。考虑模块
MODULE CT
IMPLICIT NONE
type CMT
CONTAINS
procedure, nopass :: find_line_condi
endtype CMT
CONTAINS
function find_line_condi()
integer(SELECTED_INT_KIND(4)) find_line_condi
find_line_condi=0
end function find_line_condi
END MODULE CT
比那个问题简单多了。使用 pgfortran 19.10 编译有类似的乱码输出。这个更简单的代码是否是有效的 Fortran 代码留给 reader/PGI 支持台作为练习,它应该被接受,但我认为糟糕的诊断是 PGI 希望避免的事情。
然而,这似乎是 PGI 的 LLVM 前端的一个弱点:考虑使用 pgfortran -c -Mnollvm ...
进行编译。还有一些方法可以重写代码以尝试解决此错误,例如更改函数结果的类型。
更广泛地说,PGI introduced in the 2019 releases the LLVM code generator. This seems to be going through a number of teething difficulties。如果您的代码在 PGI 2019 中意外失败(可能在 2018 中有效),那么使用 -Mnollvm
编译以使用非 LLVM 生成器值得一试。