https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92178
--- Comment #5 from Steve Kargl <sgk at troutmask dot apl.washington.edu> --- On Tue, Oct 22, 2019 at 09:03:42PM +0000, vladimir.fuka at gmail dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92178 > > --- Comment #4 from Vladimir Fuka <vladimir.fuka at gmail dot com> --- > It would be really strange if even expressions like below were not possible. > > implicit none > integer, allocatable :: a(:) > allocate(a, source=[1]) > call assign(a, (min(a(1)**2,0))) > print *, allocated(a) > contains > subroutine assign(a, i) > integer, allocatable, intent(out) :: a(:) > integer, value :: i > print *, i > end subroutine > end program Yep. I agree. In fact, if you reverse the arguments, like, implicit none integer, allocatable :: a(:) allocate(a, source=[1]) call assign((min(a(1)**2,0)), a) print *, allocated(a) contains subroutine assign(i, a) integer, allocatable, intent(out) :: a(:) integer, value :: i print *, i end subroutine end gfortran gives % gfcx -o z a.f90 && ./z 0 F Cutting the -ftree-dump-original down to the 'call' statement gives MAIN__ () { { integer(kind=4) D.3955; integer(kind=4) D.3956; integer(kind=4) M.7; D.3955 = (*(integer(kind=4)[0:] * restrict) a.data)[a.offset + 1]; D.3956 = D.3955 * D.3955; M.7 = D.3956; M.7 = MIN_EXPR <M.7, 0>; if ((integer(kind=4)[0:] * restrict) a.data != 0B) { __builtin_free ((void *) a.data); (integer(kind=4)[0:] * restrict) a.data = 0B; } assign (M.7, &a); } } which shows the argument evaluation is done correctly. In short, gfortran needs to scan the effective and dummy arguments for a deallocation and just do the right thing.