StringiFor
StringiFor copied to clipboard
gfortran ICE regression with nested allocatable derived types using getter method
The fix for bug #28 introduced a regression (or exposed a bug in gfortran 9.2.1).
module foo_m
use stringifor
implicit none
type :: foo_t
type(string), allocatable :: foo_s(:)
contains
procedure, public :: get_s
end type foo_t
type :: data_t
integer :: n_foo_s
type(foo_t), allocatable :: foo(:)
contains
procedure, public :: data_get_foo_s
end type data_t
contains
function get_s(self)
class(foo_t), intent(in) :: self
type(string) :: get_s( size(self%foo_s) )
get_s = self%foo_s
end function get_s
function data_get_foo_s(self, ith)
class(data_t), intent(in) :: self
integer, intent(in) :: ith
type(string) :: data_get_foo_s(self%n_foo_s)
data_get_foo_s = self%foo(ith)%get_s()
end function data_get_foo_s
end module foo_m
program bug_stringifor
use foo_m
implicit none
type(data_t) :: data
type(string), allocatable :: bar(:)
allocate( data%foo(1) )
data%foo(1)%foo_s = [string("alpha"), string("bravo"), string("charlie"), &
string("delta"), string("foxtrot")]
data%n_foo_s = 5
bar = data%data_get_foo_s(1)
print *, "bar = ", bar
end program bug_stringifor
$ gfortran-9 -Wall -Wextra bug_stringifor.f90 -lstringifor
bug_stringifor.f90:31:0:
31 | data_get_foo_s = self%foo(ith)%get_s()
|
internal compiler error: in gimplify_expr, at gimplify.c:13479
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-9/README.Bugs> for instructions.
$ gfortran-9 -v
Using built-in specs.
COLLECT_GCC=gfortran-9
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.2.1-17ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.2.1 20191102 (Ubuntu 9.2.1-17ubuntu1~18.04.1)
The previous version of StringiFor (before bug #28 was fixed) worked as expected and did not expose this ICE.
(Maybe the test case can be reduced further but it took me already a lot of time to reduce it to the present form from the original case.)
I forgot to mention that if this is a gfortran bug, I'm happy to report it on bugzilla. However, I would like to avoid keeping the reference to StringiFor and reduce the MWE further, but I think I would need some help since my understanding of the internals of StringiFor is limited.
@epagone thanks for reporting the bug.
I am checking it right now. btw an ICE is highly a compiler bug thus probably I can only try to find a workaround.
@epagone
I have read the test, it looks standard compliant to me. I have tested with Intel Fortran compiler and it seems to work as expected. As consequence for me is a real ICE and I cannot find a workaround for it. If you can report the bug to the GNU Fortran team I'll appreciate it very much, bugzilla is often a nightmare for me.
I left open this issue in order to try your test with future versions of GNU Fortran.
cheers
Thanks @szaghi! I have reported the ICE on bugzilla yesterday. However, I think that my test case is suboptimal because it depends directly on StringiFor (external library) and this might deter gfortran volunteers to look into the issue. If you have time, it would be great if you could help me to reduce the test case further without relying on StringiFor, but I know you're very busy.
Thank you very much for checking my test case and testing it with Intel Fortran.
@epagone I can try, but not sure when I'll have the time, sorry
@epagone I can try, but not sure when I'll have the time, sorry
FWIW, I have posted on Bugzilla a new MWE that exposes the ICE without using StringiFor. However, it might take a long time to fix the issue.
@szaghi any suggestion for a workaround? I am trying to find one with no luck and in my case using the old version of StringiFor is a pain :(
@epagone
I read your MWE, nice. However, it is really difficult for me to find a workaround. There was a version of Stringifor that does not raise this ICE? If you can tell me which version I can try to find a workaround for the current version.
The version of StringiFor prior to the fix of bug #28 (commit f906e724e829fcc21a47818fbe5fc443324d112a
) does not expose the ICE. The test case must be slightly tweaked though:
module foo_m
use stringifor
implicit none
type :: foo_t
type(string), allocatable :: foo_s(:)
contains
procedure, public :: get_s
end type foo_t
type :: data_t
integer :: n_foo_s
type(foo_t), allocatable :: foo(:)
contains
procedure, public :: data_get_foo_s
end type data_t
contains
function get_s(self)
class(foo_t), intent(in) :: self
type(string) :: get_s( size(self%foo_s) )
get_s = self%foo_s
end function get_s
function data_get_foo_s(self, ith)
class(data_t), intent(in) :: self
integer, intent(in) :: ith
type(string) :: data_get_foo_s( self%n_foo_s )
data_get_foo_s = self%foo(ith)%get_s()
end function data_get_foo_s
end module foo_m
program bug_stringifor
use foo_m
implicit none
type(data_t) :: data
type(string), allocatable :: bar(:)
data%n_foo_s = 5
allocate( data%foo(1) )
allocate( data%foo(1)%foo_s( data%n_foo_s ) )
data%foo(1)%foo_s = [string("alpha"), string("bravo"), string("charlie"), &
string("delta"), string("foxtrot")]
allocate( bar( data%n_foo_s ) )
bar = data%data_get_foo_s(1)
print *, "bar = ", bar
end program bug_stringifor
I keep my fingers crossed for a workaround, thanks for your time.
Another interesting thing that I have discovered is that a Stringifor-free version of the test case above does still expose the ICE
module foo_m
implicit none
type :: string
character(len=:), allocatable :: s
end type string
type :: foo_t
type(string), allocatable :: foo_s(:)
contains
procedure, public :: get_s
end type foo_t
type :: data_t
integer :: n_foo_s
type(foo_t), allocatable :: foo(:)
contains
procedure, public :: data_get_foo_s
end type data_t
contains
function get_s(self)
class(foo_t), intent(in) :: self
type(string) :: get_s( size(self%foo_s) )
get_s = self%foo_s
end function get_s
function data_get_foo_s(self, ith)
class(data_t), intent(in) :: self
integer, intent(in) :: ith
type(string) :: data_get_foo_s( self%n_foo_s )
data_get_foo_s = self%foo(ith)%get_s()
end function data_get_foo_s
end module foo_m
program bug_stringifor
use foo_m
implicit none
type(data_t) :: data
type(string), allocatable :: bar(:)
data%n_foo_s = 5
allocate( data%foo(1) )
allocate( data%foo(1)%foo_s( data%n_foo_s ) )
data%foo(1)%foo_s = [string("alpha"), string("bravo"), string("charlie"), &
string("delta"), string("foxtrot")]
allocate( bar( data%n_foo_s ) )
bar = data%data_get_foo_s(1)
print *, "bar = ", bar(1)%s
end program bug_stringifor
So @szaghi in StringiFor commit f906e724e829fcc21a47818fbe5fc443324d112a
you're doing something clever that does avoid the ICE with gfortran. Maybe this hint can be helpful.
@epagone
Ok, the relevant changes were the scope of raw
member (from private to public), the assignment operators becoming pure
instead of elemental
and the overloading string
name... with only 3 keys I can try to work on a workaround, but I cannot ensure timing/success :-)
For the records, my report on Bugzilla has been analysed and reduced further. I admit I do not understand clearly what is triggering the problem even after the detailed analysis, but this might help you, @szaghi. Just a heads-up.
Still present in gfortran 10.1
$ gfortran-10 -v
Using built-in specs.
COLLECT_GCC=gfortran-10
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.1.0-3ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-0TNKLK/gcc-10-10.1.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-0TNKLK/gcc-10-10.1.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.1.0 (Ubuntu 10.1.0-3ubuntu1~20.04)