! { dg-do run } ! ! Test conformance with clause 7.5.6.3, paragraph 6 of F2018. Part of PR106576. ! ! Contributed by Damian Rouson ! module finalizable_m !! This module supports the main program at the bottom of this file, which !! tests compiler conformance with clause 7.5.6.3, paragraph 6 in the Fortran !! Interpretation Document (https://j3-fortran.org/doc/year/18/18-007r1.pdf): !! "If a specification expression in a scoping unit references !! a function, the result is finalized before execution of the executable !! constructs in the scoping unit." ! NAGFOR complains about this testcase: "Error: finalize_50.f90, line 38: Rank 0 ! type FINALIZABLE_T result variable of pure function CONSTRUCT will invoke an ! impure final subroutine." ! The standard doesn't specify whether the finalization is considered to be within ! the function or not. However, given the previous paragraph, "If an executable ! construct references a nonpointer function, the result is finalized after ! execution of the innermost executable construct containing the reference.", the ! pureness of the function whose result is being finalized doesn't matter. Instead, ! it should be the pureness of the containing scope. implicit none private public :: finalizable_t, component type finalizable_t private integer, allocatable :: component_ contains final :: finalize end Type interface finalizable_t module procedure construct end interface integer, public :: final_ctr = 0 contains pure function construct(component) result(finalizable) integer, intent(in) :: component type(finalizable_t) finalizable allocate(finalizable%component_, source = component) end function pure function component(self) result(self_component) type(finalizable_t), intent(in) :: self integer self_component if (.not. allocated(self%component_)) error stop "component: unallocated component" self_component = self%component_ end function subroutine finalize(self) type(finalizable_t), intent(inout) :: self if (allocated(self%component_)) deallocate(self%component_) final_ctr = final_ctr + 1 end subroutine end module program specification_expression_finalization use finalizable_m, only : finalizable_t, component, final_ctr implicit none call finalize_specification_expression_result if (final_ctr .ne. 1) stop 1 contains subroutine finalize_specification_expression_result real tmp(component(finalizable_t(component=1))) !! Finalizes the finalizable_t function result real eliminate_unused_variable_warning tmp = eliminate_unused_variable_warning if (final_ctr .ne. 1) stop 2 end subroutine end program