https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125429

            Bug ID: 125429
           Summary: Finalization in an assignment may use temporary
                    variables out of scope
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mikael at gcc dot gnu.org
  Target Milestone: ---

Taken from PR125391 comment#16.

The variable used in the finalization guarding condition at the beginning of
save_vals has its declaration in the scalarization loop body.  Oops.


$ gfortran -c z.f90 -fdump-tree-original
z.f90:26:49:

   26 |     o(pick_first(o%available, size(o)))%items = i
      |                                                 ^
internal compiler error: in gimplify_var_or_parm_decl, at gimplify.cc:3346
0x7efcea171f76 __libc_start_call_main
        ../sysdeps/nptl/libc_start_call_main.h:58
0x7efcea172026 __libc_start_main_impl
        ../csu/libc-start.c:360
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <file:///usr/share/doc/gcc-15/README.Bugs> for instructions.
$

$ cat z.f90
module m
  implicit none
  type :: inner
    integer :: x = 0
  contains
    final :: inner_final
  end type

  type :: outer
    type(inner), allocatable :: items(:)
    logical :: available
  end type

  interface outer
    module procedure :: constructor_outer
  end interface

contains
  subroutine inner_final(this)
    type(inner), intent(inout) :: this
  end subroutine

  subroutine save_vals(o, i)
    class(outer), intent(inout) :: o(:)
    type(inner),  intent(in)    :: i(:)
    o(pick_first(o%available, size(o)))%items = i
  end subroutine

  function pick_first(a, n) result(r)
    integer,     intent(in) :: n
    logical, intent(inout)  :: a(n)
    integer                 :: r
    r = findloc(a, .true., dim=1)
    a(r) = .false.
  end function

  function constructor_outer(n) result(r)
    integer, intent(in) :: n
    type(outer) :: r
    allocate(r%items(n))
    r%available = .true.
  end function
end module

program p
  use m
  implicit none
  type(outer), allocatable :: x(:)
  integer :: failures = 0
  allocate(x(5), source = outer(3))
  call save_vals(x, [inner(-1)])
  print *, x(1)%available
  print *, x(2)%available
  if (x(1)%available) then
    call add_failure(failures, 1)
  else
    print *, "size1=", size(x(1)%items)
    if (size(x(1)%items) /= 1) then
      call add_failure(failures, 2)
    else
      print *, x(1)%items(1)%x
      if (x(1)%items(1)%x /= -1) call add_failure(failures, 4)
    end if
  end if
  if (.not. x(2)%available) then
    call add_failure(failures, 8)
    print *, 'size2=', size(x(2)%items)
    print *, x(2)%items(1)%x
  end if
  if (failures /= 0) error stop failures
contains
  subroutine add_failure(var, val)
    integer, intent(inout) :: var
    integer, intent(in)    :: val
    var = ior(var, val)
  end subroutine
end program

Reply via email to