! PR 54753 ! { dg-do compile } ! ! TS 29113 ! C535c If an assumed-size or nonallocatable nonpointer assumed-rank ! array is an actual argument corresponding to a dummy argument that ! is an INTENT(OUT) assumed-rank array, it shall not be polymorphic, [...]. ! ! This constraint is numbered C839 in the Fortran 2018 standard. ! ! This test file contains tests that are expected to issue diagnostics ! for invalid code. module t type :: t1 integer :: id real :: xyz(3) end type end module module m use t ! Assumed-type dummies are (unlimited) polymorphic too, but F2018:C709 ! already prohibits them from being declared intent(out). So we only ! test dummies of class type that are polymorphic or unlimited ! polymorphic. interface subroutine poly (x, y) use t class(t1) :: x(..) class(t1), intent (out) :: y(..) end subroutine subroutine upoly (x, y) class(*) :: x(..) class(*), intent (out) :: y(..) end subroutine end interface contains ! The known-size calls should all be OK as they do not involve ! assumed-size or assumed-rank actual arguments. subroutine test_known_size_nonpolymorphic (a1, a2, n) integer :: n type(t1) :: a1(n,n), a2(n) call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_known_size_polymorphic (a1, a2, n) integer :: n class(t1) :: a1(n,n), a2(n) call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_known_size_unlimited_polymorphic (a1, a2, n) integer :: n class(*) :: a1(n,n), a2(n) call upoly (a1, a2) end subroutine ! Likewise passing a scalar as the assumed-rank argument. subroutine test_scalar_nonpolymorphic (a1, a2) type(t1) :: a1, a2 call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_scalar_polymorphic (a1, a2) class(t1) :: a1, a2 call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_scalar_unlimited_polymorphic (a1, a2) class(*) :: a1, a2 call upoly (a1, a2) end subroutine ! The polymorphic cases for assumed-size are bad. subroutine test_assumed_size_nonpolymorphic (a1, a2) type(t1) :: a1(*), a2(*) call poly (a1, a2) ! OK call upoly (a1, a2) ! OK end subroutine subroutine test_assumed_size_polymorphic (a1, a2) class(t1) :: a1(*), a2(*) call poly (a1, a2) ! { dg-error "(A|a)ssumed.rank" } call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" } call poly (a1(5), a2(4:7)) end subroutine subroutine test_assumed_size_unlimited_polymorphic (a1, a2) class(*) :: a1(*), a2(*) call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" } end subroutine ! The arguments being passed to poly/upoly in this set are *not* ! assumed size and should not error. subroutine test_not_assumed_size_nonpolymorphic (a1, a2) type(t1) :: a1(*), a2(*) call poly (a1(5), a2(4:7)) call upoly (a1(5), a2(4:7)) call poly (a1(:10), a2(:-5)) call upoly (a1(:10), a2(:-5)) end subroutine subroutine test_not_assumed_size_polymorphic (a1, a2) class(t1) :: a1(*), a2(*) call poly (a1(5), a2(4:7)) call upoly (a1(5), a2(4:7)) call poly (a1(:10), a2(:-5)) call upoly (a1(:10), a2(:-5)) end subroutine subroutine test_not_assumed_size_unlimited_polymorphic (a1, a2) class(*) :: a1(*), a2(*) call upoly (a1(5), a2(4:7)) call upoly (a1(:10), a2(:-5)) end subroutine ! Polymorphic assumed-rank without pointer/allocatable is also bad. subroutine test_assumed_rank_nonpolymorphic (a1, a2) type(t1) :: a1(..), a2(..) call poly (a1, a2) ! OK call upoly (a1, a2) ! OK end subroutine subroutine test_assumed_rank_polymorphic (a1, a2) class(t1) :: a1(..), a2(..) call poly (a1, a2) ! { dg-error "(A|a)ssumed.rank" } call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" } end subroutine subroutine test_assumed_rank_unlimited_polymorphic (a1, a2) class(*) :: a1(..), a2(..) call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" } end subroutine ! Pointer/allocatable assumed-rank should be OK. subroutine test_pointer_nonpolymorphic (a1, a2) type(t1), pointer :: a1(..), a2(..) call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_pointer_polymorphic (a1, a2) class(t1), pointer :: a1(..), a2(..) call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_pointer_unlimited_polymorphic (a1, a2) class(*), pointer :: a1(..), a2(..) call upoly (a1, a2) end subroutine subroutine test_allocatable_nonpolymorphic (a1, a2) type(t1), allocatable :: a1(..), a2(..) call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_allocatable_polymorphic (a1, a2) class(t1), allocatable :: a1(..), a2(..) call poly (a1, a2) call upoly (a1, a2) end subroutine subroutine test_allocatable_unlimited_polymorphic (a1, a2) class(*), allocatable :: a1(..), a2(..) call upoly (a1, a2) end subroutine end module