xref: /llvm-project/flang/test/Semantics/doconcurrent08.f90 (revision 0c21377aeafc523bd4a8c40bd27e33498f3199f7)
16c1ac141SIvan Zhechev! RUN: %python %S/test_errors.py %s %flang_fc1
264ab3302SCarolineConcatto! C1140 -- A statement that might result in the deallocation of a polymorphic
364ab3302SCarolineConcatto! entity shall not appear within a DO CONCURRENT construct.
464ab3302SCarolineConcattomodule m1
564ab3302SCarolineConcatto  ! Base type with scalar components
664ab3302SCarolineConcatto  type :: Base
764ab3302SCarolineConcatto    integer :: baseField1
864ab3302SCarolineConcatto  end type
964ab3302SCarolineConcatto
1064ab3302SCarolineConcatto  ! Child type so we can allocate polymorphic entities
1164ab3302SCarolineConcatto  type, extends(Base) :: ChildType
1264ab3302SCarolineConcatto    integer :: childField
1364ab3302SCarolineConcatto  end type
1464ab3302SCarolineConcatto
1564ab3302SCarolineConcatto  ! Type with a polymorphic, allocatable component
1664ab3302SCarolineConcatto  type, extends(Base) :: HasAllocPolyType
1764ab3302SCarolineConcatto    class(Base), allocatable :: allocPolyField
1864ab3302SCarolineConcatto  end type
1964ab3302SCarolineConcatto
2064ab3302SCarolineConcatto  ! Type with a allocatable, coarray component
2164ab3302SCarolineConcatto  type :: HasAllocCoarrayType
2264ab3302SCarolineConcatto    type(Base), allocatable, codimension[:] :: allocCoarrayField
2364ab3302SCarolineConcatto  end type
2464ab3302SCarolineConcatto
2564ab3302SCarolineConcatto  ! Type with a polymorphic, allocatable, coarray component
2664ab3302SCarolineConcatto  type :: HasAllocPolyCoarrayType
2764ab3302SCarolineConcatto    class(Base), allocatable, codimension[:] :: allocPolyCoarrayField
2864ab3302SCarolineConcatto  end type
2964ab3302SCarolineConcatto
3064ab3302SCarolineConcatto  ! Type with a polymorphic, pointer component
3164ab3302SCarolineConcatto  type, extends(Base) :: HasPointerPolyType
3264ab3302SCarolineConcatto    class(Base), pointer :: pointerPolyField
3364ab3302SCarolineConcatto  end type
3464ab3302SCarolineConcatto
3564ab3302SCarolineConcatto  class(Base), allocatable :: baseVar1
3664ab3302SCarolineConcatto  type(Base) :: baseVar2
3764ab3302SCarolineConcattoend module m1
3864ab3302SCarolineConcatto
3964ab3302SCarolineConcattosubroutine s1()
4064ab3302SCarolineConcatto  ! Test deallocation of polymorphic entities caused by block exit
4164ab3302SCarolineConcatto  use m1
4264ab3302SCarolineConcatto
4364ab3302SCarolineConcatto  block
4464ab3302SCarolineConcatto    ! The following should not cause problems
4564ab3302SCarolineConcatto    integer :: outerInt
4664ab3302SCarolineConcatto
4764ab3302SCarolineConcatto    ! The following are OK since they're not in a DO CONCURRENT
4864ab3302SCarolineConcatto    class(Base), allocatable :: outerAllocatablePolyVar
4964ab3302SCarolineConcatto    class(Base), allocatable, codimension[:] :: outerAllocatablePolyCoarray
5064ab3302SCarolineConcatto    type(HasAllocPolyType), allocatable  :: outerAllocatableWithAllocPoly
5164ab3302SCarolineConcatto    type(HasAllocPolyCoarrayType), allocatable :: outerAllocWithAllocPolyCoarray
5264ab3302SCarolineConcatto
5364ab3302SCarolineConcatto    do concurrent (i = 1:10)
5464ab3302SCarolineConcatto      ! The following should not cause problems
5564ab3302SCarolineConcatto      block
5664ab3302SCarolineConcatto        integer, allocatable :: blockInt
5764ab3302SCarolineConcatto      end block
5864ab3302SCarolineConcatto      block
5964ab3302SCarolineConcatto        ! Test polymorphic entities
6064ab3302SCarolineConcatto        ! OK because it's a pointer to a polymorphic entity
6164ab3302SCarolineConcatto        class(Base), pointer :: pointerPoly
6264ab3302SCarolineConcatto
6364ab3302SCarolineConcatto        ! OK because it's not polymorphic
6464ab3302SCarolineConcatto        integer, allocatable :: intAllocatable
6564ab3302SCarolineConcatto
6664ab3302SCarolineConcatto        ! OK because it's not polymorphic
6764ab3302SCarolineConcatto        type(Base), allocatable :: allocatableNonPolyBlockVar
6864ab3302SCarolineConcatto
6964ab3302SCarolineConcatto        ! Bad because it's polymorphic and allocatable
7064ab3302SCarolineConcatto        class(Base), allocatable :: allocatablePoly
7164ab3302SCarolineConcatto
7264ab3302SCarolineConcatto        ! OK because it has the SAVE attribute
7364ab3302SCarolineConcatto        class(Base), allocatable, save :: allocatablePolySave
7464ab3302SCarolineConcatto
7564ab3302SCarolineConcatto        ! Bad because it's polymorphic and allocatable
7664ab3302SCarolineConcatto        class(Base), allocatable, codimension[:] :: allocatablePolyCoarray
7764ab3302SCarolineConcatto
7864ab3302SCarolineConcatto        ! OK because it's not polymorphic and allocatable
7964ab3302SCarolineConcatto        type(Base), allocatable, codimension[:] :: allocatableCoarray
8064ab3302SCarolineConcatto
8164ab3302SCarolineConcatto        ! Bad because it has a allocatable polymorphic component
8264ab3302SCarolineConcatto        type(HasAllocPolyType), allocatable  :: allocatableWithAllocPoly
8364ab3302SCarolineConcatto
8464ab3302SCarolineConcatto        ! OK because the declared variable is not allocatable
8564ab3302SCarolineConcatto        type(HasAllocPolyType) :: nonAllocatableWithAllocPoly
8664ab3302SCarolineConcatto
8764ab3302SCarolineConcatto        ! OK because the declared variable is not allocatable
8864ab3302SCarolineConcatto        type(HasAllocPolyCoarrayType) :: nonAllocatableWithAllocPolyCoarray
8964ab3302SCarolineConcatto
9064ab3302SCarolineConcatto        ! Bad because even though the declared the allocatable component is a coarray
9164ab3302SCarolineConcatto        type(HasAllocPolyCoarrayType), allocatable :: allocWithAllocPolyCoarray
9264ab3302SCarolineConcatto
9364ab3302SCarolineConcatto        ! OK since it has no polymorphic component
9464ab3302SCarolineConcatto        type(HasAllocCoarrayType) :: nonAllocWithAllocCoarray
9564ab3302SCarolineConcatto
9664ab3302SCarolineConcatto        ! OK since it has no component that's polymorphic, oops
9764ab3302SCarolineConcatto        type(HasPointerPolyType), allocatable :: allocatableWithPointerPoly
9864ab3302SCarolineConcatto
9964ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
10064ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
10164ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
10264ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by block exit not allowed in DO CONCURRENT
10364ab3302SCarolineConcatto      end block
10464ab3302SCarolineConcatto    end do
10564ab3302SCarolineConcatto  end block
10664ab3302SCarolineConcatto
10764ab3302SCarolineConcattoend subroutine s1
10864ab3302SCarolineConcatto
10964ab3302SCarolineConcattosubroutine s2()
11064ab3302SCarolineConcatto  ! Test deallocation of a polymorphic entity cause by intrinsic assignment
11164ab3302SCarolineConcatto  use m1
11264ab3302SCarolineConcatto
11364ab3302SCarolineConcatto  class(Base), allocatable :: localVar
11464ab3302SCarolineConcatto  class(Base), allocatable :: localVar1
11564ab3302SCarolineConcatto  type(Base), allocatable :: localVar2
11664ab3302SCarolineConcatto
11764ab3302SCarolineConcatto  type(HasAllocPolyType), allocatable :: polyComponentVar
11864ab3302SCarolineConcatto  type(HasAllocPolyType), allocatable :: polyComponentVar1
11964ab3302SCarolineConcatto
12064ab3302SCarolineConcatto  type(HasAllocPolyType) :: nonAllocPolyComponentVar
12164ab3302SCarolineConcatto  type(HasAllocPolyType) :: nonAllocPolyComponentVar1
12264ab3302SCarolineConcatto  class(HasAllocPolyCoarrayType), allocatable :: allocPolyCoarray
12364ab3302SCarolineConcatto  class(HasAllocPolyCoarrayType), allocatable :: allocPolyCoarray1
12464ab3302SCarolineConcatto
12564ab3302SCarolineConcatto  class(Base), allocatable, codimension[:] :: allocPolyComponentVar
12664ab3302SCarolineConcatto  class(Base), allocatable, codimension[:] :: allocPolyComponentVar1
12764ab3302SCarolineConcatto
12864ab3302SCarolineConcatto  allocate(ChildType :: localVar)
12964ab3302SCarolineConcatto  allocate(ChildType :: localVar1)
13064ab3302SCarolineConcatto  allocate(Base :: localVar2)
13164ab3302SCarolineConcatto  allocate(polyComponentVar)
13264ab3302SCarolineConcatto  allocate(polyComponentVar1)
13364ab3302SCarolineConcatto  allocate(allocPolyCoarray)
13464ab3302SCarolineConcatto  allocate(allocPolyCoarray1)
13564ab3302SCarolineConcatto
13664ab3302SCarolineConcatto  ! These are OK because they're not in a DO CONCURRENT
13764ab3302SCarolineConcatto  localVar = localVar1
13864ab3302SCarolineConcatto  nonAllocPolyComponentVar = nonAllocPolyComponentVar1
13964ab3302SCarolineConcatto  polyComponentVar = polyComponentVar1
14064ab3302SCarolineConcatto  allocPolyCoarray = allocPolyCoarray1
14164ab3302SCarolineConcatto
14264ab3302SCarolineConcatto  do concurrent (i = 1:10)
14364ab3302SCarolineConcatto    ! Test polymorphic entities
14464ab3302SCarolineConcatto    ! Bad because localVar is allocatable and polymorphic, 10.2.1.3, par. 3
14564ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
14664ab3302SCarolineConcatto    localVar = localVar1
14764ab3302SCarolineConcatto
14864ab3302SCarolineConcatto    ! The next one should be OK since localVar2 is not polymorphic
14964ab3302SCarolineConcatto    localVar2 = localVar1
15064ab3302SCarolineConcatto
15164ab3302SCarolineConcatto    ! Bad because the copying of the components causes deallocation
15264ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
15364ab3302SCarolineConcatto    nonAllocPolyComponentVar = nonAllocPolyComponentVar1
15464ab3302SCarolineConcatto
15564ab3302SCarolineConcatto    ! Bad because possible deallocation a variable with a polymorphic component
15664ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
15764ab3302SCarolineConcatto    polyComponentVar = polyComponentVar1
15864ab3302SCarolineConcatto
15964ab3302SCarolineConcatto    ! Bad because deallocation upon assignment happens with allocatable
16064ab3302SCarolineConcatto    ! entities, even if they're coarrays.  The noncoarray restriction only
16164ab3302SCarolineConcatto    ! applies to components
16264ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
16364ab3302SCarolineConcatto    allocPolyCoarray = allocPolyCoarray1
16464ab3302SCarolineConcatto
16564ab3302SCarolineConcatto  end do
16664ab3302SCarolineConcattoend subroutine s2
16764ab3302SCarolineConcatto
16864ab3302SCarolineConcattosubroutine s3()
16964ab3302SCarolineConcatto  ! Test direct deallocation
17064ab3302SCarolineConcatto  use m1
17164ab3302SCarolineConcatto
17264ab3302SCarolineConcatto  class(Base), allocatable :: polyVar
17364ab3302SCarolineConcatto  type(Base), allocatable :: nonPolyVar
17464ab3302SCarolineConcatto  type(HasAllocPolyType), allocatable :: polyComponentVar
17564ab3302SCarolineConcatto  type(HasAllocPolyType), pointer :: pointerPolyComponentVar
17664ab3302SCarolineConcatto
17764ab3302SCarolineConcatto  allocate(ChildType:: polyVar)
17864ab3302SCarolineConcatto  allocate(nonPolyVar)
17964ab3302SCarolineConcatto  allocate(polyComponentVar)
18064ab3302SCarolineConcatto  allocate(pointerPolyComponentVar)
18164ab3302SCarolineConcatto
18264ab3302SCarolineConcatto  ! These are all good because they're not in a do concurrent
18364ab3302SCarolineConcatto  deallocate(polyVar)
18464ab3302SCarolineConcatto  allocate(polyVar)
18564ab3302SCarolineConcatto  deallocate(polyComponentVar)
18664ab3302SCarolineConcatto  allocate(polyComponentVar)
18764ab3302SCarolineConcatto  deallocate(pointerPolyComponentVar)
18864ab3302SCarolineConcatto  allocate(pointerPolyComponentVar)
18964ab3302SCarolineConcatto
19064ab3302SCarolineConcatto  do concurrent (i = 1:10)
19164ab3302SCarolineConcatto    ! Bad because deallocation of a polymorphic entity
19264ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by a DEALLOCATE statement not allowed in DO CONCURRENT
19364ab3302SCarolineConcatto    deallocate(polyVar)
19464ab3302SCarolineConcatto
19564ab3302SCarolineConcatto    ! Bad, deallocation of an entity with a polymorphic component
19664ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by a DEALLOCATE statement not allowed in DO CONCURRENT
19764ab3302SCarolineConcatto    deallocate(polyComponentVar)
19864ab3302SCarolineConcatto
19964ab3302SCarolineConcatto    ! Bad, deallocation of a pointer to an entity with a polymorphic component
20064ab3302SCarolineConcatto!ERROR: Deallocation of a polymorphic entity caused by a DEALLOCATE statement not allowed in DO CONCURRENT
20164ab3302SCarolineConcatto    deallocate(pointerPolyComponentVar)
20264ab3302SCarolineConcatto
20364ab3302SCarolineConcatto    ! Deallocation of a nonpolymorphic entity
20464ab3302SCarolineConcatto    deallocate(nonPolyVar)
20564ab3302SCarolineConcatto  end do
20664ab3302SCarolineConcattoend subroutine s3
20764ab3302SCarolineConcatto
20864ab3302SCarolineConcattomodule m2
20964ab3302SCarolineConcatto  type :: impureFinal
21064ab3302SCarolineConcatto   contains
21164ab3302SCarolineConcatto    final :: impureSub
212*0c21377aSKelvin Li    final :: impureSubRank1
213*0c21377aSKelvin Li    final :: impureSubRank2
21464ab3302SCarolineConcatto  end type
21564ab3302SCarolineConcatto
21664ab3302SCarolineConcatto  type :: pureFinal
21764ab3302SCarolineConcatto   contains
21864ab3302SCarolineConcatto    final :: pureSub
21964ab3302SCarolineConcatto  end type
22064ab3302SCarolineConcatto
22164ab3302SCarolineConcatto contains
22264ab3302SCarolineConcatto
22364ab3302SCarolineConcatto  impure subroutine impureSub(x)
22464ab3302SCarolineConcatto    type(impureFinal), intent(in) :: x
22564ab3302SCarolineConcatto  end subroutine
22664ab3302SCarolineConcatto
227*0c21377aSKelvin Li  impure subroutine impureSubRank1(x)
228*0c21377aSKelvin Li    type(impureFinal), intent(in) :: x(:)
229*0c21377aSKelvin Li  end subroutine
230*0c21377aSKelvin Li
231*0c21377aSKelvin Li  impure subroutine impureSubRank2(x)
232*0c21377aSKelvin Li    type(impureFinal), intent(in) :: x(:,:)
233*0c21377aSKelvin Li  end subroutine
234*0c21377aSKelvin Li
23564ab3302SCarolineConcatto  pure subroutine pureSub(x)
23664ab3302SCarolineConcatto    type(pureFinal), intent(in) :: x
23764ab3302SCarolineConcatto  end subroutine
23864ab3302SCarolineConcatto
23964ab3302SCarolineConcatto  subroutine s4()
24064ab3302SCarolineConcatto    type(impureFinal), allocatable :: ifVar, ifvar1
241*0c21377aSKelvin Li    type(impureFinal), allocatable :: ifArr1(:), ifArr2(:,:)
242*0c21377aSKelvin Li    type(impureFinal) :: if0
24364ab3302SCarolineConcatto    type(pureFinal), allocatable :: pfVar
24464ab3302SCarolineConcatto    allocate(ifVar)
24564ab3302SCarolineConcatto    allocate(ifVar1)
24664ab3302SCarolineConcatto    allocate(pfVar)
247*0c21377aSKelvin Li    allocate(ifArr1(5), ifArr2(5,5))
24864ab3302SCarolineConcatto
24964ab3302SCarolineConcatto    ! OK for an ordinary DO loop
25064ab3302SCarolineConcatto    do i = 1,10
25164ab3302SCarolineConcatto      if (i .eq. 1) deallocate(ifVar)
25264ab3302SCarolineConcatto    end do
25364ab3302SCarolineConcatto
25464ab3302SCarolineConcatto    ! OK to invoke a PURE FINAL procedure in a DO CONCURRENT
255*0c21377aSKelvin Li    do concurrent (i = 1:10)
256*0c21377aSKelvin Li      if (i .eq. 1) deallocate(pfVar)
257*0c21377aSKelvin Li    end do
25864ab3302SCarolineConcatto
25964ab3302SCarolineConcatto    ! Error to invoke an IMPURE FINAL procedure in a DO CONCURRENT
26064ab3302SCarolineConcatto    do concurrent (i = 1:10)
261e9a8ab00SPeter Klausler      !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresub' caused by a DEALLOCATE statement not allowed in DO CONCURRENT
26264ab3302SCarolineConcatto      if (i .eq. 1) deallocate(ifVar)
26364ab3302SCarolineConcatto    end do
26464ab3302SCarolineConcatto
26564ab3302SCarolineConcatto    do concurrent (i = 1:10)
26664ab3302SCarolineConcatto      if (i .eq. 1) then
26764ab3302SCarolineConcatto        block
26864ab3302SCarolineConcatto          type(impureFinal), allocatable :: ifVar
26964ab3302SCarolineConcatto          allocate(ifVar)
27064ab3302SCarolineConcatto          ! Error here because exiting this scope causes the finalization of
27164ab3302SCarolineConcatto          ! ifvar which causes the invocation of an IMPURE FINAL procedure
272e9a8ab00SPeter Klausler          !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresub' caused by block exit not allowed in DO CONCURRENT
27364ab3302SCarolineConcatto        end block
27464ab3302SCarolineConcatto      end if
27564ab3302SCarolineConcatto    end do
27664ab3302SCarolineConcatto
27764ab3302SCarolineConcatto    do concurrent (i = 1:10)
27864ab3302SCarolineConcatto      if (i .eq. 1) then
27964ab3302SCarolineConcatto        ! Error here because the assignment statement causes the finalization
28064ab3302SCarolineConcatto        ! of ifvar which causes the invocation of an IMPURE FINAL procedure
281e9a8ab00SPeter Klausler        !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresub' caused by assignment not allowed in DO CONCURRENT
28264ab3302SCarolineConcatto        ifvar = ifvar1
28364ab3302SCarolineConcatto      end if
28464ab3302SCarolineConcatto    end do
285*0c21377aSKelvin Li
286*0c21377aSKelvin Li    do concurrent (i = 1:5)
287*0c21377aSKelvin Li      if (i .eq. 1) then
288*0c21377aSKelvin Li        !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresub' caused by assignment not allowed in DO CONCURRENT
289*0c21377aSKelvin Li        ifArr1(i) = if0
290*0c21377aSKelvin Li      end if
291*0c21377aSKelvin Li    end do
292*0c21377aSKelvin Li
293*0c21377aSKelvin Li    do concurrent (i = 1:5)
294*0c21377aSKelvin Li      if (i .eq. 1) then
295*0c21377aSKelvin Li        !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresubrank1' caused by assignment not allowed in DO CONCURRENT
296*0c21377aSKelvin Li        ifArr1 = if0
297*0c21377aSKelvin Li      end if
298*0c21377aSKelvin Li    end do
299*0c21377aSKelvin Li
300*0c21377aSKelvin Li    do concurrent (i = 1:5)
301*0c21377aSKelvin Li      if (i .eq. 1) then
302*0c21377aSKelvin Li        !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresubrank1' caused by assignment not allowed in DO CONCURRENT
303*0c21377aSKelvin Li        ifArr2(i,:) = if0
304*0c21377aSKelvin Li      end if
305*0c21377aSKelvin Li    end do
306*0c21377aSKelvin Li
307*0c21377aSKelvin Li    do concurrent (i = 1:5)
308*0c21377aSKelvin Li      if (i .eq. 1) then
309*0c21377aSKelvin Li        !ERROR: Deallocation of an entity with an IMPURE FINAL procedure 'impuresubrank2' caused by assignment not allowed in DO CONCURRENT
310*0c21377aSKelvin Li        ifArr2(:,:) = if0
311*0c21377aSKelvin Li      end if
312*0c21377aSKelvin Li    end do
31364ab3302SCarolineConcatto  end subroutine s4
31464ab3302SCarolineConcatto
31564ab3302SCarolineConcattoend module m2
316