2020-05-12 02:38:53 +08:00
|
|
|
! RUN: %S/test_errors.sh %s %t %f18
|
[flang] Changes to check for constraint C1140
This constraint prohibits deallocation of polymorphic entities in a DO
CONCURRENT.
Section 9.7.3.2 specifies the situations that might cause deallocation
of a polymorphic entity. The ones that are applicable to a DO CONCURRENT
are exiting from a block that declares such variables, intrinsic
assignment, and an actual DEALLOCATE statement. This section also
specifies (paragraph 8) that deallocation of a derived type causes
deallocation of all of its allocatable subobjects.
Section 10.2.1.3 specifies what happens during intrinsic assignment.
Paragraph 3 states If the variable is an allocated allocatable variable,
it is deallocated if expr is an array of different shape, any
corresponding length type parameter values of the variable and expr
differ, or the variable is polymorphic and the dynamic type or any
corresponding kind type parameter values of the variable and expr
differ." Thus, an allocatable polymorphic variable on the left hand side
of an assignment statement gets deallocated. Paragraph 13 states that
"For a noncoarray allocatable component the following sequence of
operations is applied.
(1) If the component of the variable is allocated, it is deallocated."
Thus, a variable on the left-hand side of an assignment statement might have noncorray allocatable components. Such components will be deallocated.
Deallocation can be caused by exiting from a block where the entity is
declared, from an assignment, and from direct deallocation.
Original-commit: flang-compiler/f18@7d1932d344308d8266503268a7534532cebe6087
Reviewed-on: https://github.com/flang-compiler/f18/pull/814
2019-11-06 02:18:33 +08:00
|
|
|
! C1140 -- A statement that might result in the deallocation of a polymorphic
|
|
|
|
! entity shall not appear within a DO CONCURRENT construct.
|
|
|
|
module m1
|
|
|
|
! Base type with scalar components
|
|
|
|
type :: Base
|
|
|
|
integer :: baseField1
|
|
|
|
end type
|
|
|
|
|
|
|
|
! Child type so we can allocate polymorphic entities
|
|
|
|
type, extends(Base) :: ChildType
|
|
|
|
integer :: childField
|
|
|
|
end type
|
|
|
|
|
|
|
|
! Type with a polymorphic, allocatable component
|
|
|
|
type, extends(Base) :: HasAllocPolyType
|
|
|
|
class(Base), allocatable :: allocPolyField
|
|
|
|
end type
|
|
|
|
|
|
|
|
! Type with a allocatable, coarray component
|
|
|
|
type :: HasAllocCoarrayType
|
|
|
|
type(Base), allocatable, codimension[:] :: allocCoarrayField
|
|
|
|
end type
|
|
|
|
|
|
|
|
! Type with a polymorphic, allocatable, coarray component
|
|
|
|
type :: HasAllocPolyCoarrayType
|
|
|
|
class(Base), allocatable, codimension[:] :: allocPolyCoarrayField
|
|
|
|
end type
|
|
|
|
|
|
|
|
! Type with a polymorphic, pointer component
|
|
|
|
type, extends(Base) :: HasPointerPolyType
|
|
|
|
class(Base), pointer :: pointerPolyField
|
|
|
|
end type
|
|
|
|
|
|
|
|
class(Base), allocatable :: baseVar1
|
|
|
|
type(Base) :: baseVar2
|
|
|
|
end module m1
|
|
|
|
|
|
|
|
subroutine s1()
|
|
|
|
! Test deallocation of polymorphic entities caused by block exit
|
|
|
|
use m1
|
|
|
|
|
|
|
|
block
|
|
|
|
! The following should not cause problems
|
|
|
|
integer :: outerInt
|
|
|
|
|
|
|
|
! The following are OK since they're not in a DO CONCURRENT
|
|
|
|
class(Base), allocatable :: outerAllocatablePolyVar
|
|
|
|
class(Base), allocatable, codimension[:] :: outerAllocatablePolyCoarray
|
|
|
|
type(HasAllocPolyType), allocatable :: outerAllocatableWithAllocPoly
|
|
|
|
type(HasAllocPolyCoarrayType), allocatable :: outerAllocWithAllocPolyCoarray
|
|
|
|
|
|
|
|
do concurrent (i = 1:10)
|
|
|
|
! The following should not cause problems
|
|
|
|
block
|
|
|
|
integer, allocatable :: blockInt
|
|
|
|
end block
|
|
|
|
block
|
|
|
|
! Test polymorphic entities
|
|
|
|
! OK because it's a pointer to a polymorphic entity
|
|
|
|
class(Base), pointer :: pointerPoly
|
|
|
|
|
|
|
|
! OK because it's not polymorphic
|
|
|
|
integer, allocatable :: intAllocatable
|
|
|
|
|
|
|
|
! OK because it's not polymorphic
|
|
|
|
type(Base), allocatable :: allocatableNonPolyBlockVar
|
|
|
|
|
|
|
|
! Bad because it's polymorphic and allocatable
|
|
|
|
class(Base), allocatable :: allocatablePoly
|
|
|
|
|
|
|
|
! OK because it has the SAVE attribute
|
|
|
|
class(Base), allocatable, save :: allocatablePolySave
|
|
|
|
|
|
|
|
! Bad because it's polymorphic and allocatable
|
|
|
|
class(Base), allocatable, codimension[:] :: allocatablePolyCoarray
|
|
|
|
|
|
|
|
! OK because it's not polymorphic and allocatable
|
|
|
|
type(Base), allocatable, codimension[:] :: allocatableCoarray
|
|
|
|
|
|
|
|
! Bad because it has a allocatable polymorphic component
|
|
|
|
type(HasAllocPolyType), allocatable :: allocatableWithAllocPoly
|
|
|
|
|
|
|
|
! OK because the declared variable is not allocatable
|
|
|
|
type(HasAllocPolyType) :: nonAllocatableWithAllocPoly
|
|
|
|
|
|
|
|
! OK because the declared variable is not allocatable
|
|
|
|
type(HasAllocPolyCoarrayType) :: nonAllocatableWithAllocPolyCoarray
|
|
|
|
|
|
|
|
! Bad because even though the declared the allocatable component is a coarray
|
|
|
|
type(HasAllocPolyCoarrayType), allocatable :: allocWithAllocPolyCoarray
|
|
|
|
|
|
|
|
! OK since it has no polymorphic component
|
|
|
|
type(HasAllocCoarrayType) :: nonAllocWithAllocCoarray
|
|
|
|
|
|
|
|
! OK since it has no component that's polymorphic, oops
|
|
|
|
type(HasPointerPolyType), allocatable :: allocatableWithPointerPoly
|
|
|
|
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
|
|
|
|
end block
|
|
|
|
end do
|
|
|
|
end block
|
|
|
|
|
|
|
|
end subroutine s1
|
|
|
|
|
|
|
|
subroutine s2()
|
|
|
|
! Test deallocation of a polymorphic entity cause by intrinsic assignment
|
|
|
|
use m1
|
|
|
|
|
|
|
|
class(Base), allocatable :: localVar
|
|
|
|
class(Base), allocatable :: localVar1
|
|
|
|
type(Base), allocatable :: localVar2
|
|
|
|
|
|
|
|
type(HasAllocPolyType), allocatable :: polyComponentVar
|
|
|
|
type(HasAllocPolyType), allocatable :: polyComponentVar1
|
|
|
|
|
|
|
|
type(HasAllocPolyType) :: nonAllocPolyComponentVar
|
|
|
|
type(HasAllocPolyType) :: nonAllocPolyComponentVar1
|
|
|
|
class(HasAllocPolyCoarrayType), allocatable :: allocPolyCoarray
|
|
|
|
class(HasAllocPolyCoarrayType), allocatable :: allocPolyCoarray1
|
|
|
|
|
|
|
|
class(Base), allocatable, codimension[:] :: allocPolyComponentVar
|
|
|
|
class(Base), allocatable, codimension[:] :: allocPolyComponentVar1
|
|
|
|
|
|
|
|
allocate(ChildType :: localVar)
|
|
|
|
allocate(ChildType :: localVar1)
|
|
|
|
allocate(Base :: localVar2)
|
|
|
|
allocate(polyComponentVar)
|
|
|
|
allocate(polyComponentVar1)
|
|
|
|
allocate(allocPolyCoarray)
|
|
|
|
allocate(allocPolyCoarray1)
|
|
|
|
|
|
|
|
! These are OK because they're not in a DO CONCURRENT
|
|
|
|
localVar = localVar1
|
|
|
|
nonAllocPolyComponentVar = nonAllocPolyComponentVar1
|
|
|
|
polyComponentVar = polyComponentVar1
|
|
|
|
allocPolyCoarray = allocPolyCoarray1
|
|
|
|
|
|
|
|
do concurrent (i = 1:10)
|
|
|
|
! Test polymorphic entities
|
|
|
|
! Bad because localVar is allocatable and polymorphic, 10.2.1.3, par. 3
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
|
|
|
|
localVar = localVar1
|
|
|
|
|
|
|
|
! The next one should be OK since localVar2 is not polymorphic
|
|
|
|
localVar2 = localVar1
|
|
|
|
|
|
|
|
! Bad because the copying of the components causes deallocation
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
|
|
|
|
nonAllocPolyComponentVar = nonAllocPolyComponentVar1
|
|
|
|
|
|
|
|
! Bad because possible deallocation a variable with a polymorphic component
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
|
|
|
|
polyComponentVar = polyComponentVar1
|
|
|
|
|
|
|
|
! Bad because deallocation upon assignment happens with allocatable
|
|
|
|
! entities, even if they're coarrays. The noncoarray restriction only
|
|
|
|
! applies to components
|
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
|
|
|
|
allocPolyCoarray = allocPolyCoarray1
|
|
|
|
|
|
|
|
end do
|
|
|
|
end subroutine s2
|
|
|
|
|
|
|
|
subroutine s3()
|
|
|
|
! Test direct deallocation
|
|
|
|
use m1
|
|
|
|
|
|
|
|
class(Base), allocatable :: polyVar
|
|
|
|
type(Base), allocatable :: nonPolyVar
|
|
|
|
type(HasAllocPolyType), allocatable :: polyComponentVar
|
|
|
|
type(HasAllocPolyType), pointer :: pointerPolyComponentVar
|
|
|
|
|
|
|
|
allocate(ChildType:: polyVar)
|
|
|
|
allocate(nonPolyVar)
|
|
|
|
allocate(polyComponentVar)
|
|
|
|
allocate(pointerPolyComponentVar)
|
|
|
|
|
|
|
|
! These are all good because they're not in a do concurrent
|
|
|
|
deallocate(polyVar)
|
|
|
|
allocate(polyVar)
|
|
|
|
deallocate(polyComponentVar)
|
|
|
|
allocate(polyComponentVar)
|
|
|
|
deallocate(pointerPolyComponentVar)
|
|
|
|
allocate(pointerPolyComponentVar)
|
|
|
|
|
|
|
|
do concurrent (i = 1:10)
|
|
|
|
! Bad because deallocation of a polymorphic entity
|
2020-01-28 06:12:35 +08:00
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by a DEALLOCATE statement not allowed in DO CONCURRENT
|
[flang] Changes to check for constraint C1140
This constraint prohibits deallocation of polymorphic entities in a DO
CONCURRENT.
Section 9.7.3.2 specifies the situations that might cause deallocation
of a polymorphic entity. The ones that are applicable to a DO CONCURRENT
are exiting from a block that declares such variables, intrinsic
assignment, and an actual DEALLOCATE statement. This section also
specifies (paragraph 8) that deallocation of a derived type causes
deallocation of all of its allocatable subobjects.
Section 10.2.1.3 specifies what happens during intrinsic assignment.
Paragraph 3 states If the variable is an allocated allocatable variable,
it is deallocated if expr is an array of different shape, any
corresponding length type parameter values of the variable and expr
differ, or the variable is polymorphic and the dynamic type or any
corresponding kind type parameter values of the variable and expr
differ." Thus, an allocatable polymorphic variable on the left hand side
of an assignment statement gets deallocated. Paragraph 13 states that
"For a noncoarray allocatable component the following sequence of
operations is applied.
(1) If the component of the variable is allocated, it is deallocated."
Thus, a variable on the left-hand side of an assignment statement might have noncorray allocatable components. Such components will be deallocated.
Deallocation can be caused by exiting from a block where the entity is
declared, from an assignment, and from direct deallocation.
Original-commit: flang-compiler/f18@7d1932d344308d8266503268a7534532cebe6087
Reviewed-on: https://github.com/flang-compiler/f18/pull/814
2019-11-06 02:18:33 +08:00
|
|
|
deallocate(polyVar)
|
|
|
|
|
|
|
|
! Bad, deallocation of an entity with a polymorphic component
|
2020-01-28 06:12:35 +08:00
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by a DEALLOCATE statement not allowed in DO CONCURRENT
|
[flang] Changes to check for constraint C1140
This constraint prohibits deallocation of polymorphic entities in a DO
CONCURRENT.
Section 9.7.3.2 specifies the situations that might cause deallocation
of a polymorphic entity. The ones that are applicable to a DO CONCURRENT
are exiting from a block that declares such variables, intrinsic
assignment, and an actual DEALLOCATE statement. This section also
specifies (paragraph 8) that deallocation of a derived type causes
deallocation of all of its allocatable subobjects.
Section 10.2.1.3 specifies what happens during intrinsic assignment.
Paragraph 3 states If the variable is an allocated allocatable variable,
it is deallocated if expr is an array of different shape, any
corresponding length type parameter values of the variable and expr
differ, or the variable is polymorphic and the dynamic type or any
corresponding kind type parameter values of the variable and expr
differ." Thus, an allocatable polymorphic variable on the left hand side
of an assignment statement gets deallocated. Paragraph 13 states that
"For a noncoarray allocatable component the following sequence of
operations is applied.
(1) If the component of the variable is allocated, it is deallocated."
Thus, a variable on the left-hand side of an assignment statement might have noncorray allocatable components. Such components will be deallocated.
Deallocation can be caused by exiting from a block where the entity is
declared, from an assignment, and from direct deallocation.
Original-commit: flang-compiler/f18@7d1932d344308d8266503268a7534532cebe6087
Reviewed-on: https://github.com/flang-compiler/f18/pull/814
2019-11-06 02:18:33 +08:00
|
|
|
deallocate(polyComponentVar)
|
|
|
|
|
|
|
|
! Bad, deallocation of a pointer to an entity with a polymorphic component
|
2020-01-28 06:12:35 +08:00
|
|
|
!ERROR: Deallocation of a polymorphic entity caused by a DEALLOCATE statement not allowed in DO CONCURRENT
|
[flang] Changes to check for constraint C1140
This constraint prohibits deallocation of polymorphic entities in a DO
CONCURRENT.
Section 9.7.3.2 specifies the situations that might cause deallocation
of a polymorphic entity. The ones that are applicable to a DO CONCURRENT
are exiting from a block that declares such variables, intrinsic
assignment, and an actual DEALLOCATE statement. This section also
specifies (paragraph 8) that deallocation of a derived type causes
deallocation of all of its allocatable subobjects.
Section 10.2.1.3 specifies what happens during intrinsic assignment.
Paragraph 3 states If the variable is an allocated allocatable variable,
it is deallocated if expr is an array of different shape, any
corresponding length type parameter values of the variable and expr
differ, or the variable is polymorphic and the dynamic type or any
corresponding kind type parameter values of the variable and expr
differ." Thus, an allocatable polymorphic variable on the left hand side
of an assignment statement gets deallocated. Paragraph 13 states that
"For a noncoarray allocatable component the following sequence of
operations is applied.
(1) If the component of the variable is allocated, it is deallocated."
Thus, a variable on the left-hand side of an assignment statement might have noncorray allocatable components. Such components will be deallocated.
Deallocation can be caused by exiting from a block where the entity is
declared, from an assignment, and from direct deallocation.
Original-commit: flang-compiler/f18@7d1932d344308d8266503268a7534532cebe6087
Reviewed-on: https://github.com/flang-compiler/f18/pull/814
2019-11-06 02:18:33 +08:00
|
|
|
deallocate(pointerPolyComponentVar)
|
|
|
|
|
|
|
|
! Deallocation of a nonpolymorphic entity
|
|
|
|
deallocate(nonPolyVar)
|
|
|
|
end do
|
|
|
|
end subroutine s3
|
2020-01-28 06:12:35 +08:00
|
|
|
|
|
|
|
module m2
|
|
|
|
type :: impureFinal
|
|
|
|
contains
|
|
|
|
final :: impureSub
|
|
|
|
end type
|
|
|
|
|
|
|
|
type :: pureFinal
|
|
|
|
contains
|
|
|
|
final :: pureSub
|
|
|
|
end type
|
|
|
|
|
|
|
|
contains
|
|
|
|
|
|
|
|
impure subroutine impureSub(x)
|
|
|
|
type(impureFinal), intent(in) :: x
|
|
|
|
end subroutine
|
|
|
|
|
|
|
|
pure subroutine pureSub(x)
|
|
|
|
type(pureFinal), intent(in) :: x
|
|
|
|
end subroutine
|
|
|
|
|
|
|
|
subroutine s4()
|
|
|
|
type(impureFinal), allocatable :: ifVar, ifvar1
|
|
|
|
type(pureFinal), allocatable :: pfVar
|
|
|
|
allocate(ifVar)
|
|
|
|
allocate(ifVar1)
|
|
|
|
allocate(pfVar)
|
|
|
|
|
|
|
|
! OK for an ordinary DO loop
|
|
|
|
do i = 1,10
|
|
|
|
if (i .eq. 1) deallocate(ifVar)
|
|
|
|
end do
|
|
|
|
|
|
|
|
! OK to invoke a PURE FINAL procedure in a DO CONCURRENT
|
|
|
|
! This case does not work currently because the compiler's test for
|
2020-02-25 23:11:52 +08:00
|
|
|
! HasImpureFinal() in .../lib/Semantics/tools.cc doesn't work correctly
|
2020-01-28 06:12:35 +08:00
|
|
|
! do concurrent (i = 1:10)
|
|
|
|
! if (i .eq. 1) deallocate(pfVar)
|
|
|
|
! end do
|
|
|
|
|
|
|
|
! Error to invoke an IMPURE FINAL procedure in a DO CONCURRENT
|
|
|
|
do concurrent (i = 1:10)
|
|
|
|
!ERROR: Deallocation of an entity with an IMPURE FINAL procedure caused by a DEALLOCATE statement not allowed in DO CONCURRENT
|
|
|
|
if (i .eq. 1) deallocate(ifVar)
|
|
|
|
end do
|
|
|
|
|
|
|
|
do concurrent (i = 1:10)
|
|
|
|
if (i .eq. 1) then
|
|
|
|
block
|
|
|
|
type(impureFinal), allocatable :: ifVar
|
|
|
|
allocate(ifVar)
|
|
|
|
! Error here because exiting this scope causes the finalization of
|
|
|
|
!ifvar which causes the invocation of an IMPURE FINAL procedure
|
|
|
|
!ERROR: Deallocation of an entity with an IMPURE FINAL procedure caused by block exit not allowed in DO CONCURRENT
|
|
|
|
end block
|
|
|
|
end if
|
|
|
|
end do
|
|
|
|
|
|
|
|
do concurrent (i = 1:10)
|
|
|
|
if (i .eq. 1) then
|
|
|
|
! Error here because the assignment statement causes the finalization
|
|
|
|
! of ifvar which causes the invocation of an IMPURE FINAL procedure
|
|
|
|
!ERROR: Deallocation of an entity with an IMPURE FINAL procedure caused by assignment not allowed in DO CONCURRENT
|
|
|
|
ifvar = ifvar1
|
|
|
|
end if
|
|
|
|
end do
|
|
|
|
end subroutine s4
|
|
|
|
|
|
|
|
end module m2
|