This is an archive of the discontinued LLVM Phabricator instance.

[flang] Deallocate intent(out) allocatables
ClosedPublic

Authored by clementval on Sep 6 2022, 4:54 AM.

Details

Summary

From Fortran 2018 standard 9.7.3.2 point 6:
When a procedure is invoked, any allocated allocatable object that is an actual
argument corresponding to an INTENT (OUT) allocatable dummy argument is
deallocated; any allocated allocatable object that is a subobject of an actual
argument corresponding to an INTENT (OUT) dummy argument is deallocated.

Deallocation is done on the callee side. For BIND(C) procedure, the deallocation
is also done on the caller side.

Diff Detail

Event Timeline

clementval created this revision.Sep 6 2022, 4:54 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptSep 6 2022, 4:54 AM
Herald added a subscriber: mehdi_amini. · View Herald Transcript
clementval requested review of this revision.Sep 6 2022, 4:54 AM

any allocated allocatable object that is a subobject of an actual argument corresponding to an INTENT (OUT) dummy argument is deallocated

Did you intend to implement this part ? I do not think the patch covers it (I would expect something checking if some non allocatable derived type object with allocatable components are intent(out)).

Also, is this possible for OPTIONAL allocatable to be intent(out) ? If so, the deallocation may have to be conditional for optionals.

Otherwise the logic looks good to me.

clementval added a comment.EditedSep 6 2022, 6:31 AM

any allocated allocatable object that is a subobject of an actual argument corresponding to an INTENT (OUT) dummy argument is deallocated

Did you intend to implement this part ? I do not think the patch covers it (I would expect something checking if some non allocatable derived type object with allocatable components are intent(out)).

It is implemented on the callee side already with the default initialization of the derived type.

module mod1
type t1
  integer, allocatable :: a(:)
end type
contains
  subroutine sub(d)
    type(t1), intent(out) :: d
    if (allocated(d%a)) print*,'fail'
  end
end

use mod1
type(t1) :: t

allocate(t%a(10))
call sub(t)
end

This small test is already passing. I'll update the caller side with bind(c).

Also, is this possible for OPTIONAL allocatable to be intent(out) ? If so, the deallocation may have to be conditional for optionals.

Yes it is. I'll add the condition for that.

Otherwise the logic looks good to me.

Handle allocatable components and optional allocatables

jeanPerier added inline comments.
flang/lib/Lower/ConvertVariable.cpp
628–631

I do not remember the logic of genDeallocateBox, is this OK to call if the allocatable is unallocated ? Otherwise, some more conditional logic is probably needed here.

flang/test/Lower/intentout-deallocate.f90
34

Reading the standard again, I think bind(c) procedure cannot have a derived type with allocatable component.

  • C1554: "If proc-language-binding-spec is specified for a procedure, each of its dummy arguments shall be an interoperable procedure (18.3.6) or a variable that is interoperable (18.3.4, 18.3.5), assumed-shape, assumedrank, assumed-type, of type CHARACTER with assumed length, or that has the ALLOCATABLE or POINTER attribute."
  • 18.3.3 point 2: "A derived type is interoperable with a C structure type if and only if the derived type has the BIND attribute [....]"
  • C1806: "Each component of a derived type with the BIND attribute shall be a nonpointer, nonallocatable data component with interoperable type and type parameters."

My conclusion of this is that this is illegal, and you do not need to care about INTENT(OUT) derived types with allocatable components on the caller side for BIND(C). gfortran rejects this, but not ifort (and flang semantics currently).

Since the appositions in C1554 make it highly unreadable to me, you probably want to double check this with @klausler.

klausler added inline comments.Sep 7 2022, 8:28 AM
flang/test/Lower/intentout-deallocate.f90
34

C1554 literally implies that the type of a dummy argument variable is irrelevant in several cases (assumed-shape, assumed-rank, allocatable, pointer) and that is difficult for me to understand as well. However, it is possible that the context intends for C1554 to apply only to procedure definitions, not interfaces, since it's in subclause 15.6..

Remove non-conform tests

clementval marked 3 inline comments as done.Sep 7 2022, 12:40 PM
clementval added inline comments.
flang/lib/Lower/ConvertVariable.cpp
628–631

Yes it is fine to call it with an unallocated box.

flang/test/Lower/intentout-deallocate.f90
34

I removed those tests.

This revision is now accepted and ready to land.Sep 8 2022, 12:38 AM
This revision was automatically updated to reflect the committed changes.
clementval marked an inline comment as done.