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

Paul Thomas <pault at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |pault at gcc dot gnu.org

--- Comment #2 from Paul Thomas <pault at gcc dot gnu.org> ---
Created attachment 57820
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57820&action=edit
Draft fix for this PR

Many thanks for the report.

The attachment needs some cleaning up and testing with other variants that
might generate the problem.

In fact, this is a double regression since the testcase below does not give the
right result for 'x' in the calls to test1 and test2.

The first regression is associated with the derived type having zero components
messing up the finalization calls. Strictly, this is not a regression since the
older versions of gfortran did not attempt the finalization.

The second regression is due to the attempt to place finalization calls in the
correct place relative to the evaluation of the rhs and the assignment to the
lhs. This is the cause of the incorrect results for the testcase below. I
believe that the correct output is:
after test1 x =    2   3
no. final calls =    4
after test2 x =    6   8
no. final calls =   12

nagfor agrees but ifort gives 3 and 8 respectively for the no. of
finalizations.

To my astonishment, given the current stage of the fix, it even regtests OK :-)

Paul

module types
  type t
     integer :: i
   contains
     final :: finalize
  end type t
  integer :: ctr = 0
contains
  impure elemental subroutine finalize(x)
    type(t), intent(inout) :: x
    ctr = ctr + 1
  end subroutine finalize
end module types

impure elemental function elem(x)
  use types
  type(t), intent(in) :: x
  type(t) :: elem
  elem%i = x%i + 1
end function elem

impure elemental function elem2(x, y)
  use types
  type(t), intent(in) :: x, y
  type(t) :: elem2
  elem2%i = x%i + y%i
end function elem2

subroutine test1(x)
  use types
  interface
     impure elemental function elem(x)
       use types
       type(t), intent(in) :: x
       type(t) :: elem
     end function elem
  end interface
  type(t) :: x(:)
  x = elem(x)
end subroutine test1

subroutine test2(x)
  use types
  interface
     impure elemental function elem(x)
       use types
       type(t), intent(in) :: x
       type(t) :: elem
     end function elem
     impure elemental function elem2(x, y)
       use types
       type(t), intent(in) :: x, y
       type(t) :: elem2
     end function elem2
  end interface
  type(t) :: x(:)
  x = elem2(elem(x), elem(x))
end subroutine test2

program test113885
  use types
  interface
    subroutine test1(x)
      use types
      type(t) :: x(:)
    end subroutine
    subroutine test2(x)
      use types
      type(t) :: x(:)
    end subroutine
  end interface
  type(t) :: x(2) = [t(1),t(2)]
  call test1 (x)
  print "(a, 2i4)", "after test1 x = ", x
  print "(a, i4)", "no. final calls = ", ctr
  call test2 (x)
  print "(a, 2i4)", "after test2 x = ", x
  print "(a, i4)", "no. final calls = ",ctr
end
  • [Bug fortran/113885] [13/14 Reg... pault at gcc dot gnu.org via Gcc-bugs

Reply via email to