StringiFor icon indicating copy to clipboard operation
StringiFor copied to clipboard

gfortran ICE regression with nested allocatable derived types using getter method

Open epagone opened this issue 5 years ago • 12 comments

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.)

epagone avatar Nov 18 '19 17:11 epagone

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 avatar Nov 19 '19 12:11 epagone

@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.

szaghi avatar Nov 20 '19 10:11 szaghi

@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

szaghi avatar Nov 20 '19 11:11 szaghi

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 avatar Nov 20 '19 13:11 epagone

@epagone I can try, but not sure when I'll have the time, sorry

szaghi avatar Nov 20 '19 13:11 szaghi

@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 avatar Nov 24 '19 19:11 epagone

@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.

szaghi avatar Nov 25 '19 10:11 szaghi

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.

epagone avatar Nov 25 '19 12:11 epagone

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 avatar Nov 25 '19 13:11 epagone

@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 :-)

szaghi avatar Nov 25 '19 13:11 szaghi

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.

epagone avatar Dec 20 '19 12:12 epagone

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) 

epagone avatar Jul 13 '20 11:07 epagone