Recently I stumbled across the following issue when switching from gfortran (gcc 9.3) to ifort (intel 19.2) (changing from local machine to cluster).
Reducing it to a MWE revealed the passing of an assumed-shape (:) character array to a module subroutine. This is the code
module mymod
implicit none
interface
module integer function func(arg, l)
integer :: l
character(len=l), dimension(:), intent(in) :: arg
end function
end interface
end module
submodule (mymod) submod
implicit none
contains
module procedure func
implicit none
func = size(arg)
end procedure
end submodule
program myprog
use mymod
implicit none
write(*,*) func(["xy", "ab", "ij"], 2)
end program
And this is the error thrown by ifort:
myprog.f90: catastrophic error: **Internal compiler error: segmentation violation signal raised** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error.
compilation aborted for myprog.f90 (code 1)
The original intent of my function is obviously something different and a bit more complex, but the concept is the same since it would require the size() intrinsic to be available for arg (or lbound and ubound).
Stuff making the error go away and maintain the purpose
using an
assumed-length+assumed-shapedummy argument:module integer function func(arg) character(len=*), dimension(:), intent(in) :: arg end functionWorks with an allocatable character variable as argument in
func()and with the constructor. This is my favourite solution since I can drop thelwhich I really didn't need in the first place.not using an interfaced
module functionand submodule with themodule procedurebut an internal function in the modulemymodscontainssectionusing
assumed-lengthandassumed-shape+allocatablein the dummy argumentcharacter(len=:), dimension(:), allocatable, intent(in) :: argwhich requires a likewise allocatable variable to be used when calling
func(instead of the constructor expression of the example, which might or might not proove to be annoying)
Stuff making the error go away but are not an option
- switching to
assumed-sizeinstead ofassumed-shape:
character(len=l), dimension(*)but thensizeintrinsic won't work (yay, a different error, which was to be expected) - having an
integerarray instead ofcharacter(obviously only to check if its the case for any assumed-shape, interfaced module procedure... it's not)
Stuff not changing the error
- simply adding
allocatableto the dummy variable declaration while keeping the defined lengthlen=lpart (and using an allocatable variable as argument when callingfunc)
As the code works with the adjustment of (len=*) (making it no longer an deferred length character which is fine by me) my main question concernes the different behaviours of the compilers.
Is it right that gfortran compiles this and the program behaves as intended — making this a bug in ifort — or is it wrong that gfortran does this?