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.

Reply via email to