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

--- Comment #17 from Mikael Morin <mikael at gcc dot gnu.org> ---
(In reply to Mikael Morin from comment #11)
> The pre and post block dropped would be automatically fixed if the double
> evaluation is fixed. 

Here is an example nevertheless.  In this variant of comment #16, the variable
isn't out of scope, but it's still used uninitialized.
Tested with 15.2 and patched master.

$ gfortran -static y.f90 -o y
$ ./y

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
 (... blah blah ...)


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

  type :: outer
    type(inner), allocatable :: item
    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_val(o, i)
    class(outer), intent(inout) :: o(:)
    type(inner),  intent(in)    :: i
    o(pick_first(o%available, size(o)))%item = 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() result(r)
    type(outer) :: r
    allocate(r%item)
    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())
  call save_val(x, inner(-1))
  print *, x(1)%available
  print *, x(2)%available
  if (x(1)%available) then
    call add_failure(failures, 1)
  else
    print *, x(1)%item%x
  end if
  if (.not. x(2)%available) then
    print *, x(2)%item%x
    call add_failure(failures, 2)
  end if
  if (x(1)%item%x /= -1) call add_failure(failures, 4)
  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