Bug 93678 - [11/12/13/14 Regression] ICE with TRANSFER and typebound procedures
Summary: [11/12/13/14 Regression] ICE with TRANSFER and typebound procedures
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 9.2.1
: P4 normal
Target Milestone: 11.5
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2020-02-11 15:25 UTC by Luis Kornblueh
Modified: 2023-07-07 10:36 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.4.1
Known to fail: 10.0, 8.3.1, 9.2.1
Last reconfirmed: 2020-02-12 00:00:00


Attachments
Fortran source file (3.67 KB, text/plain)
2020-02-11 15:25 UTC, Luis Kornblueh
Details
New testcase (582 bytes, text/plain)
2020-02-13 15:44 UTC, Luis Kornblueh
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Luis Kornblueh 2020-02-11 15:25:07 UTC
Created attachment 47818 [details]
Fortran source file

The reduced code snippet has been working fine for a long time
gcc-6 up to gcc-9.1 but is broken know with 9.2 and 9.2.1.
The problem is reproducable on Darwin and Linux. It does compile
fine with intel-14 up to intel-19, pgi-17 up to pgi-19, nag 6.0 up to nag-6.2
cray ftn 8.4 to 8.7, and latest NEC Fortran.

___________________________________________________________________________________
Exact version of GCC

% gfortran --version
GNU Fortran (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008
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.

___________________________________________________________________________________
System type

% uname -a
Linux chulung 5.3.0-29-generic #31-Ubuntu SMP Fri Jan 17 17:27:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

% lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 19.10
Release:	19.10
Codename:	eoan

___________________________________________________________________________________
Options given when GCC was configured/built

% gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
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-9ubuntu2' --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-bootstrap --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-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 20191008 (Ubuntu 9.2.1-9ubuntu2) 

___________________________________________________________________________________
Complete command line that triggers the bug

% gfortran -c -Wall -Wextra regression-or-bug.f90

___________________________________________________________________________________
Compiler output (error messages, warnings, etc.)

regression-or-bug.f90:601:0:

  601 |      val = TRANSFER(me%unpackBytes(TRANSFER( val, characterArrayMold)),  val)
      | 
internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-9/README.Bugs> for instructions.
Comment 1 kargls 2020-02-11 20:26:21 UTC
Reduced testcase.

Have no idea if original code and/or this testcase is valid Fortran.
My suspicion is that the original code is invalid.

module mo_a

   implicit none

   type t_b
      integer n
      contains
         procedure :: unpackint => b_unpackint
         procedure :: unpackbytes => b_unpackbytes  
   end type t_b

   contains

      function b_unpackbytes(me, s) result(res)
         class(t_b), intent(inout) :: me
         character, intent(in) :: s(:)
         character, pointer :: res(:)
         res => null()
         if (len(s) == 1) me%n = 42
      end function b_unpackbytes

      subroutine b_unpackint(me, val)
         class(t_b), intent(inout) :: me
         integer, intent(out) :: val
         character :: c(1)
         c = transfer(val, c)
         val = transfer(me%unpackbytes(c),  val)
      end subroutine b_unpackint
end module mo_a
Comment 2 Luis Kornblueh 2020-02-13 15:44:49 UTC
Created attachment 47838 [details]
New testcase
Comment 3 Luis Kornblueh 2020-02-13 15:46:17 UTC
Thanks @kargl for simplifing my still very long case. However, a bug has been introduced in this version.

The nested transfers cannot be split into two as the result of the first transfer is not a character :: c(1) result, but, in the nested case a 
presumably  character :: tmp(4) array to keep an integer. which gets passed to the outer transfer. A write another, a bit bigger case, doing things correctly.

I created a new testcase, a little bit larger, but, as I think, correct Fortran.
Comment 4 Steve Kargl 2020-02-13 17:15:03 UTC
On Thu, Feb 13, 2020 at 03:46:17PM +0000, mail.luis at web dot de wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93678
> 
> --- Comment #3 from Luis Kornblueh <mail.luis at web dot de> ---
> Thanks @kargl for simplifing my still very long case. However, a bug has been
> introduced in this version.
> 
> The nested transfers cannot be split into two as the result of the first
> transfer is not a character :: c(1) result, but, in the nested case a 
> presumably  character :: tmp(4) array to keep an integer. which gets passed to
> the outer transfer. A write another, a bit bigger case, doing things correctly.
> 
> I created a new testcase, a little bit larger, but, as I think, correct
> Fortran.
> 

I was trying to get to the minimum code required to
trigger the bug.
Comment 5 Thomas Koenig 2020-07-12 12:55:40 UTC
A somewhat smaller test case, which of course does nothing useful,
but still reproduces the ICE:

module mo_a
  implicit none
  type t_b
     integer :: n = 0
     integer :: nr = 0
     character, pointer :: buffer(:) => NULL()
   contains
     procedure :: unpackbytes => b_unpackbytes  
  end type t_b
  character :: characterarraymold(1)
contains
  subroutine b_unpackint(me, val)
    class(t_b), intent(inout) :: me
    integer, intent(out) :: val
    val = transfer(me%unpackbytes(transfer(val, characterarraymold)),  val)
  end subroutine b_unpackint
  function b_unpackbytes(me, bytearraymold) result(res)
    class(t_b), intent(inout) :: me
    character, intent(in) :: bytearraymold(:)
    character, pointer :: res(:)
  end function b_unpackbytes
end module mo_a
Comment 6 Thomas Koenig 2020-07-12 13:08:50 UTC
So, it is the typebound procedure that causes the problem.

This does not ICE:

    val = transfer(b_unpackbytes(me, characterarraymold), val)

But this does ICE:

    val = transfer(me%unpackbytes(characterarraymold), val)
Comment 7 anlauf 2020-10-30 20:31:21 UTC
(In reply to Thomas Koenig from comment #5)
> A somewhat smaller test case, which of course does nothing useful,
> but still reproduces the ICE:

Further reduced / simplified:

module mo_a
  implicit none
  type t_b
  contains
    procedure :: unpackbytes => b_unpackbytes  
  end type t_b
contains
  subroutine b_unpackint (me)
    class(t_b), intent(inout) :: me
    integer :: val
    val = transfer (me% unpackbytes ("*"), val)
  end subroutine b_unpackint
  function b_unpackbytes (me, bytearraymold) result (res)
    class(t_b), intent(inout) :: me
    character(*), intent(in)  :: bytearraymold
    character                 :: res(1)
  end function b_unpackbytes
end module mo_a
Comment 8 anlauf 2020-10-30 20:48:30 UTC
Further reduced:

module mo_a
  implicit none
  type t_b
  contains
    procedure :: unpackbytes => b_unpackbytes  
  end type t_b
contains
  function b_unpackbytes (me) result (res)
    class(t_b), intent(inout) :: me
    character                 :: res(1)
  end function b_unpackbytes
  subroutine b_unpackint (me)
    class(t_b), intent(inout) :: me
!   print *, b_unpackbytes (me) ! ok
    print *, me% unpackbytes () ! ICE
  end subroutine b_unpackint
end module mo_a


The "arrayness" of the result res seems to be key.
Comment 9 anlauf 2020-10-30 21:03:06 UTC
Another data point: comparing the -fdump-fortran-original of

    res = b_unpackbytes (me) ! ok

vs.

    res = me% unpackbytes () ! ICE

I see:

    ASSIGN b_unpackint:res(FULL) b_unpackbytes[[((b_unpackint:me))]]

vs.

    ASSIGN b_unpackint:res(FULL) b_unpackbytes % _vptr % unpackbytes[[((b_unpackint:me))]]

This hasn't changed since gcc-7.  Maybe Paul(?) has some idea?
Comment 10 Richard Biener 2021-06-01 08:16:21 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 11 Richard Biener 2022-05-27 09:42:06 UTC
GCC 9 branch is being closed
Comment 12 Jakub Jelinek 2022-06-28 10:39:43 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 13 Richard Biener 2023-07-07 10:36:45 UTC
GCC 10 branch is being closed.