1! { dg-do run } 2 3 interface 4 subroutine sub1 (x, y) 5 integer, intent(in) :: y(:) 6 integer, intent(out) :: x(:) 7 end subroutine 8 function fn2 (x, m1, m2, n1, n2) 9 integer, intent(in) :: x(:,:), m1, m2, n1, n2 10 integer :: fn2(m1:m2,n1:n2) 11 end function 12 subroutine sub3 (x, y) 13 integer, allocatable, intent(in) :: y(:,:) 14 integer, allocatable, intent(inout) :: x(:,:) 15 end subroutine 16 end interface 17!$omp declare reduction (foo : integer : sub3 (omp_out, omp_in)) & 18!$omp initializer (omp_priv = fn3 (omp_orig)) 19!$omp declare reduction (bar : integer : omp_out = fn1 (omp_out, omp_in, & 20!$omp & lbound (omp_out, 1), ubound (omp_out, 1))) & 21!$omp & initializer (sub1 (omp_priv, omp_orig)) 22!$omp declare reduction (baz : integer : sub2 (omp_out, omp_in)) & 23!$omp initializer (omp_priv = fn2 (omp_orig, lbound (omp_priv, 1), & 24!$omp ubound (omp_priv, 1), lbound (omp_priv, 2), ubound (omp_priv, 2))) 25 interface 26 function fn1 (x, y, m1, m2) 27 integer, intent(in) :: x(:), y(:), m1, m2 28 integer :: fn1(m1:m2) 29 end function 30 subroutine sub2 (x, y) 31 integer, intent(in) :: y(:,:) 32 integer, intent(inout) :: x(:,:) 33 end subroutine 34 function fn3 (x) 35 integer, allocatable, intent(in) :: x(:,:) 36 integer, allocatable :: fn3(:,:) 37 end function 38 end interface 39 integer :: a(10), b(3:5,7:9), r 40 integer, allocatable :: c(:,:) 41 a(:) = 0 42 r = 0 43!$omp parallel reduction (bar : a) reduction (+: r) 44 if (lbound (a, 1) /= 1 .or. ubound (a, 1) /= 10) call abort 45 a = a + 2 46 r = r + 1 47!$omp end parallel 48 if (any (a /= 4 * r) ) call abort 49 b(:,:) = 0 50 allocate (c (4:6,8:10)) 51 c(:,:) = 0 52 r = 0 53!$omp parallel reduction (baz : b, c) reduction (+: r) 54 if (lbound (b, 1) /= 3 .or. ubound (b, 1) /= 5) call abort 55 if (lbound (b, 2) /= 7 .or. ubound (b, 2) /= 9) call abort 56 if (.not. allocated (c)) call abort 57 if (lbound (c, 1) /= 4 .or. ubound (c, 1) /= 6) call abort 58 if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 10) call abort 59 b = b + 3 60 c = c + 4 61 r = r + 1 62!$omp end parallel 63 if (any (b /= 3 * r) .or. any (c /= 4 * r)) call abort 64 deallocate (c) 65 allocate (c (0:1,7:11)) 66 c(:,:) = 0 67 r = 0 68!$omp parallel reduction (foo : c) reduction (+: r) 69 if (.not. allocated (c)) call abort 70 if (lbound (c, 1) /= 0 .or. ubound (c, 1) /= 1) call abort 71 if (lbound (c, 2) /= 7 .or. ubound (c, 2) /= 11) call abort 72 c = c + 5 73 r = r + 1 74!$omp end parallel 75 if (any (c /= 10 * r)) call abort 76end 77function fn1 (x, y, m1, m2) 78 integer, intent(in) :: x(:), y(:), m1, m2 79 integer :: fn1(m1:m2) 80 fn1 = x + 2 * y 81end function 82subroutine sub1 (x, y) 83 integer, intent(in) :: y(:) 84 integer, intent(out) :: x(:) 85 x = 0 86end subroutine 87function fn2 (x, m1, m2, n1, n2) 88 integer, intent(in) :: x(:,:), m1, m2, n1, n2 89 integer :: fn2(m1:m2,n1:n2) 90 fn2 = x 91end function 92subroutine sub2 (x, y) 93 integer, intent(inout) :: x(:,:) 94 integer, intent(in) :: y(:,:) 95 x = x + y 96end subroutine 97function fn3 (x) 98 integer, allocatable, intent(in) :: x(:,:) 99 integer, allocatable :: fn3(:,:) 100 fn3 = x 101end function 102subroutine sub3 (x, y) 103 integer, allocatable, intent(inout) :: x(:,:) 104 integer, allocatable, intent(in) :: y(:,:) 105 x = x + 2 * y 106end subroutine 107