1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
! RUN: %python %S/test_errors.py %s %flang_fc1
! Test 15.7 C1591 & others: contexts requiring pure subprograms
module m
type :: t
contains
procedure, nopass :: tbp_pure => pure
procedure, nopass :: tbp_impure => impure
end type
type, extends(t) :: t2
contains
!ERROR: An overridden pure type-bound procedure binding must also be pure
procedure, nopass :: tbp_pure => impure ! 7.5.7.3
end type
contains
pure integer function pure(n)
integer, value :: n
pure = n
end function
impure integer function impure(n)
integer, value :: n
impure = n
end function
subroutine test
real :: a(pure(1)) ! ok
!ERROR: Invalid specification expression: reference to impure function 'impure'
real :: b(impure(1)) ! 10.1.11(4)
forall (j=1:1)
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
a(j) = impure(j) ! C1037
end forall
forall (j=1:1)
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
a(j) = pure(impure(j)) ! C1037
end forall
!ERROR: DO CONCURRENT mask expression may not reference impure procedure 'impure'
do concurrent (j=1:1, impure(j) /= 0) ! C1121
!ERROR: Impure procedure 'impure' may not be referenced in DO CONCURRENT
a(j) = impure(j) ! C1139
end do
!WARNING: Impure procedure 'impure' should not be referenced in a DO CONCURRENT header
do concurrent (k=impure(1):1); end do
!WARNING: Impure procedure 'impure' should not be referenced in a DO CONCURRENT header
do concurrent (k=1:impure(1)); end do
!WARNING: Impure procedure 'impure' should not be referenced in a DO CONCURRENT header
do concurrent (k=1:1:impure(1)); end do
!WARNING: Impure procedure 'impure' should not be referenced in a FORALL header
forall (k=impure(1):1); end forall
!WARNING: Impure procedure 'impure' should not be referenced in a FORALL header
forall (k=1:impure(1)); end forall
!WARNING: Impure procedure 'impure' should not be referenced in a FORALL header
forall (k=1:1:impure(1)); end forall
do concurrent (j=1:1)
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
do concurrent (k=impure(1):1); end do
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
do concurrent (k=1:impure(1)); end do
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
do concurrent (k=1:1:impure(1)); end do
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
forall (k=impure(1):1); end forall
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
forall (k=1:impure(1)); end forall
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
forall (k=1:1:impure(1)); end forall
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
forall (k=impure(1):1) a(k) = 0.
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
forall (k=1:impure(1)) a(k) = 0.
!ERROR: Impure procedure 'impure' may not be referenced in a DO CONCURRENT
forall (k=1:1:impure(1)) a(k) = 0.
end do
forall (j=1:1)
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
forall (k=impure(1):1); end forall
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
forall (k=1:impure(1)); end forall
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
forall (k=1:1:impure(1)); end forall
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
forall (k=impure(1):1) a(j*k) = 0.
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
forall (k=1:impure(1)) a(j*k) = 0.
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
forall (k=1:1:impure(1)) a(j*k) = 0.
end forall
end subroutine
subroutine test2
type(t) :: x
real :: a(x%tbp_pure(1)) ! ok
!ERROR: Invalid specification expression: reference to impure function 'impure'
real :: b(x%tbp_impure(1))
forall (j=1:1)
a(j) = x%tbp_pure(j) ! ok
end forall
forall (j=1:1)
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
a(j) = x%tbp_impure(j) ! C1037
end forall
do concurrent (j=1:1, x%tbp_pure(j) /= 0) ! ok
a(j) = x%tbp_pure(j) ! ok
end do
!ERROR: DO CONCURRENT mask expression may not reference impure procedure 'impure'
do concurrent (j=1:1, x%tbp_impure(j) /= 0) ! C1121
!ERROR: Impure procedure 'impure' may not be referenced in DO CONCURRENT
a(j) = x%tbp_impure(j) ! C1139
end do
end subroutine
subroutine test3
type :: t
integer :: i
end type
type(t) :: a(10), b
forall (i=1:10)
a(i) = t(pure(i)) ! OK
end forall
forall (i=1:10)
!ERROR: Impure procedure 'impure' may not be referenced in a FORALL
a(i) = t(impure(i)) ! C1037
end forall
end subroutine
subroutine test4(ch)
type :: t
real, allocatable :: x
end type
type(t) :: a(1), b(1)
character(*), intent(in) :: ch
allocate (b(1)%x)
! Intrinsic functions and a couple subroutines are pure; do not emit errors
do concurrent (j=1:1)
b(j)%x = cos(1.) + len(ch)
call move_alloc(from=b(j)%x, to=a(j)%x)
end do
end subroutine
end module
|