Bug 106731 - ICE on automatic array of derived type with DTIO
Summary: ICE on automatic array of derived type with DTIO
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 12.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2022-08-24 07:44 UTC by federico
Modified: 2022-11-08 21:11 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-08-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description federico 2022-08-24 07:44:49 UTC
A derived type that has user-defined I/O causes ICE on all gfortran versions 7 to 12.1.0, whenever it's being used as an automatic object.

The error is at 


   63 |         type(t) :: automatic(n)
      |                               1
internal compiler error: in gfc_trans_auto_array_allocation, at fortran/trans-array.cc:6617

This does not happen if the derived type is allocated.

Here's the simplest example: 

module causes_ice
    implicit none

    type :: t
        real(8) :: x
        contains
        procedure, private :: write_formatted
        generic :: write(formatted) => write_formatted
    end type t

    contains

    subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg)
       class(t), intent(in) :: this
       integer, intent(in) :: unit
       character(*), intent(in) :: iotype
       integer, intent(in) :: v_list(:)
       integer, intent(out) :: iostat
       character(*), intent(inout) :: iomsg
       write(unit, '(a)', iostat=iostat, iomsg=iomsg) 'dummy'
    end subroutine write_formatted

end module causes_ice

module use_t
    use causes_ice
    implicit none

    public :: automatic_alloc

    contains

    subroutine automatic_alloc(n)
        integer, intent(in) :: n

        ! Automatic array: ICE!
        type(t) :: automatic(n)

        ! Allocatable: works
        type(t), allocatable :: alloc(:)
        allocate(alloc(n))

        ! Do anything
        print *, 'n=',n,automatic(n)%x

    end subroutine automatic_alloc

end module use_t

program test
    use use_t
    call automatic_alloc(1)
end program test

I could find other DTIO-related bugs, but none seemed related with the allocation type.
Comment 1 Martin Liška 2022-08-24 07:49:51 UTC
Likely started with r7-2882-ge73d3ca6d1caf9c1.
Comment 2 federico 2022-08-24 08:22:12 UTC
For the sake of completeness, fixed-size does not cause an ICE: 

type(t) :: fixed(5) ! works
Comment 3 kargl 2022-08-24 17:38:22 UTC
(In reply to federico from comment #0)
> A derived type that has user-defined I/O causes ICE on all gfortran versions
> 7 to 12.1.0, whenever it's being used as an automatic object.
> 
> The error is at 
> 
> 
>    63 |         type(t) :: automatic(n)
>       |                               1
> internal compiler error: in gfc_trans_auto_array_allocation, at
> fortran/trans-array.cc:6617
> 
> This does not happen if the derived type is allocated.
> 
> Here's the simplest example: 
> 
> module causes_ice
>     implicit none
> 
>     type :: t
>         real(8) :: x
>         contains
>         procedure, private :: write_formatted
>         generic :: write(formatted) => write_formatted
>     end type t
> 
>     contains
> 
>     subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg)
>        class(t), intent(in) :: this
>        integer, intent(in) :: unit
>        character(*), intent(in) :: iotype
>        integer, intent(in) :: v_list(:)
>        integer, intent(out) :: iostat
>        character(*), intent(inout) :: iomsg
>        write(unit, '(a)', iostat=iostat, iomsg=iomsg) 'dummy'
>     end subroutine write_formatted
> 
> end module causes_ice
> 
> module use_t
>     use causes_ice
>     implicit none
> 
>     public :: automatic_alloc
> 
>     contains
> 
>     subroutine automatic_alloc(n)
>         integer, intent(in) :: n
> 
>         ! Automatic array: ICE!
>         type(t) :: automatic(n)
> 
>         ! Allocatable: works
>         type(t), allocatable :: alloc(:)
>         allocate(alloc(n))
> 
>         ! Do anything
>         print *, 'n=',n,automatic(n)%x
> 
>     end subroutine automatic_alloc
> 
> end module use_t
> 
> program test
>     use use_t
>     call automatic_alloc(1)
> end program test
> 
> I could find other DTIO-related bugs, but none seemed related with the
> allocation type.

You're hitting an assert() in trans-array.cc.  It's unclear to me why the assert() is there.  If it is commented out, the code compiles and executes.

% git diff gcc/fortran/trans-array.cc | cat
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 05134952db4..c5916aeee53 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -6614,7 +6614,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
   type = TREE_TYPE (type);
 
   gcc_assert (!sym->attr.use_assoc);
-  gcc_assert (!TREE_STATIC (decl));
+//  gcc_assert (!TREE_STATIC (decl));
   gcc_assert (!sym->module);
 
   if (sym->ts.type == BT_CHARACTER
Comment 4 federico 2022-08-24 19:10:20 UTC
The TREE_STATIC assert should be valid according to what reported in the implementation at report https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48298 

But, I can't tell what that means.
Comment 5 Steve Kargl 2022-08-24 19:27:22 UTC
On Wed, Aug 24, 2022 at 07:10:20PM +0000, federico.perini at gmail dot com wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106731
> 
> --- Comment #4 from federico <federico.perini at gmail dot com> ---
> The TREE_STATIC assert should be valid according to what reported in the
> implementation at report https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48298 
> 
> But, I can't tell what that means.
> 

I can only report what I find.  If the gcc_assert()
is commented out your code compiles and executes.
Whether the output is correct or not, I don't know
as I don't use DTIO.  I guess someone else will need
to fire up gdb and debug this problem for you.
Comment 6 federico 2022-08-25 07:16:52 UTC
Yeah this popped up playing with DTIO, this feature is not widely used apparently. I'll also try to get a copy of the gcc source code and build pipeline to see if I can help.
Comment 7 anlauf 2022-11-08 21:11:06 UTC
(In reply to federico from comment #4)
> The TREE_STATIC assert should be valid according to what reported in the
> implementation at report https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48298 
> 
> But, I can't tell what that means.

I did a "git blame" on gcc/fortran/trans-array.cc, and that says that the
last change of the offentding line was in 2004.  The corresponding commit
replaced assert() by gcc_assert().  Haven't looked further, but I guess you
should really try Steve's patch and see if it not only fixes your problem,
but regtests ok and maybe works for cases not yet in the testsuite.