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