summaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-16 14:43:37 +0000
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-16 14:43:37 +0000
commit22f273dd122dd5e98dc9cfac46679d5ae9820f39 (patch)
treed900c1f5612876011350fce385e3405b655aed32 /libgomp
parentadbd300ac2f701398d973750759b0460c8c79364 (diff)
downloadlinaro-gcc-22f273dd122dd5e98dc9cfac46679d5ae9820f39.tar.gz
linaro-gcc-22f273dd122dd5e98dc9cfac46679d5ae9820f39.tar.bz2
linaro-gcc-22f273dd122dd5e98dc9cfac46679d5ae9820f39.zip
Merge branches/gcc-4_9-branch rev 212419
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@212661 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/ChangeLog102
-rw-r--r--libgomp/omp_lib.f90.in2
-rw-r--r--libgomp/omp_lib.h.in2
-rw-r--r--libgomp/testsuite/libgomp.c/target-8.c26
-rw-r--r--libgomp/testsuite/libgomp.fortran/aligned1.f03133
-rw-r--r--libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90328
-rw-r--r--libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90367
-rw-r--r--libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90372
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable10.f90112
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable11.f9072
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable12.f9074
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable9.f90156
-rw-r--r--libgomp/testsuite/libgomp.fortran/associate1.f9023
-rw-r--r--libgomp/testsuite/libgomp.fortran/associate2.f9046
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-do-1.f9014
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-do-2.f9090
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f9010
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-parallel-3.f9038
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-sections-1.f9023
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f9028
-rw-r--r--libgomp/testsuite/libgomp.fortran/declare-simd-1.f9095
-rw-r--r--libgomp/testsuite/libgomp.fortran/declare-simd-2.f9025
-rw-r--r--libgomp/testsuite/libgomp.fortran/declare-simd-3.f9022
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-1.f90203
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-2.f9034
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-3.f9042
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn5.f9096
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic5.f9059
-rw-r--r--libgomp/testsuite/libgomp.fortran/openmp_version-1.f2
-rw-r--r--libgomp/testsuite/libgomp.fortran/openmp_version-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/procptr1.f9042
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd1.f9035
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd2.f90101
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd3.f90109
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd4.f90103
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd5.f90124
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd6.f90135
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd7.f90172
-rw-r--r--libgomp/testsuite/libgomp.fortran/target1.f9058
-rw-r--r--libgomp/testsuite/libgomp.fortran/target2.f9096
-rw-r--r--libgomp/testsuite/libgomp.fortran/target3.f9029
-rw-r--r--libgomp/testsuite/libgomp.fortran/target4.f9048
-rw-r--r--libgomp/testsuite/libgomp.fortran/target5.f9021
-rw-r--r--libgomp/testsuite/libgomp.fortran/target6.f9050
-rw-r--r--libgomp/testsuite/libgomp.fortran/target7.f9038
-rw-r--r--libgomp/testsuite/libgomp.fortran/target8.f9033
-rw-r--r--libgomp/testsuite/libgomp.fortran/taskgroup1.f9080
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr1.f9051
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr10.f9032
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr11.f9095
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr12.f9076
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr13.f90106
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr14.f9050
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr15.f9064
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr2.f9051
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr3.f9038
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr4.f9050
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr5.f9057
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr6.f9069
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr7.f9046
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr8.f9046
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr9.f9065
62 files changed, 4764 insertions, 4 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index aaa7ddec68f..00e34875ead 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,105 @@
+2014-06-30 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2014-06-25 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/simd5.f90: New test.
+ * testsuite/libgomp.fortran/simd6.f90: New test.
+ * testsuite/libgomp.fortran/simd7.f90: New test.
+
+ 2014-06-24 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/aligned1.f03: New test.
+ * testsuite/libgomp.fortran/nestedfn5.f90: New test.
+ * testsuite/libgomp.fortran/target7.f90: Surround loop spawning
+ tasks with !$omp parallel !$omp single.
+ * testsuite/libgomp.fortran/target8.f90: New test.
+ * testsuite/libgomp.fortran/udr4.f90 (foo UDR, bar UDR): Adjust
+ not to use trim in the combiner, instead call elemental function.
+ (fn): New elemental function.
+ * testsuite/libgomp.fortran/udr6.f90 (do_add, dp_add, dp_init):
+ Make elemental.
+ * testsuite/libgomp.fortran/udr7.f90 (omp_priv, omp_orig, omp_out,
+ omp_in): Likewise.
+ * testsuite/libgomp.fortran/udr12.f90: New test.
+ * testsuite/libgomp.fortran/udr13.f90: New test.
+ * testsuite/libgomp.fortran/udr14.f90: New test.
+ * testsuite/libgomp.fortran/udr15.f90: New test.
+
+ 2014-06-18 Jakub Jelinek <jakub@redhat.com>
+
+ * omp_lib.f90.in (openmp_version): Set to 201307.
+ * omp_lib.h.in (openmp_version): Likewise.
+ * testsuite/libgomp.c/target-8.c: New test.
+ * testsuite/libgomp.fortran/declare-simd-1.f90: Add notinbranch
+ and inbranch clauses.
+ * testsuite/libgomp.fortran/depend-3.f90: New test.
+ * testsuite/libgomp.fortran/openmp_version-1.f: Adjust for new
+ openmp_version.
+ * testsuite/libgomp.fortran/openmp_version-2.f90: Likewise.
+ * testsuite/libgomp.fortran/target1.f90: New test.
+ * testsuite/libgomp.fortran/target2.f90: New test.
+ * testsuite/libgomp.fortran/target3.f90: New test.
+ * testsuite/libgomp.fortran/target4.f90: New test.
+ * testsuite/libgomp.fortran/target5.f90: New test.
+ * testsuite/libgomp.fortran/target6.f90: New test.
+ * testsuite/libgomp.fortran/target7.f90: New test.
+
+ 2014-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/60928
+ * testsuite/libgomp.fortran/allocatable9.f90: New test.
+ * testsuite/libgomp.fortran/allocatable10.f90: New test.
+ * testsuite/libgomp.fortran/allocatable11.f90: New test.
+ * testsuite/libgomp.fortran/allocatable12.f90: New test.
+ * testsuite/libgomp.fortran/alloc-comp-1.f90: New test.
+ * testsuite/libgomp.fortran/alloc-comp-2.f90: New test.
+ * testsuite/libgomp.fortran/alloc-comp-3.f90: New test.
+ * testsuite/libgomp.fortran/associate1.f90: New test.
+ * testsuite/libgomp.fortran/associate2.f90: New test.
+ * testsuite/libgomp.fortran/procptr1.f90: New test.
+
+ 2014-06-06 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/simd1.f90: New test.
+ * testsuite/libgomp.fortran/udr1.f90: New test.
+ * testsuite/libgomp.fortran/udr2.f90: New test.
+ * testsuite/libgomp.fortran/udr3.f90: New test.
+ * testsuite/libgomp.fortran/udr4.f90: New test.
+ * testsuite/libgomp.fortran/udr5.f90: New test.
+ * testsuite/libgomp.fortran/udr6.f90: New test.
+ * testsuite/libgomp.fortran/udr7.f90: New test.
+ * testsuite/libgomp.fortran/udr8.f90: New test.
+ * testsuite/libgomp.fortran/udr9.f90: New test.
+ * testsuite/libgomp.fortran/udr10.f90: New test.
+ * testsuite/libgomp.fortran/udr11.f90: New test.
+
+ 2014-05-27 Uros Bizjak <ubizjak@gmail.com>
+
+ * testsuite/libgomp.fortran/declare-simd-1.f90: Require
+ vect_simd_clones effective target.
+ * testsuite/libgomp.fortran/declare-simd-2.f90: Ditto.
+
+ 2014-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/cancel-do-1.f90: New test.
+ * testsuite/libgomp.fortran/cancel-do-2.f90: New test.
+ * testsuite/libgomp.fortran/cancel-parallel-1.f90: New test.
+ * testsuite/libgomp.fortran/cancel-parallel-3.f90: New test.
+ * testsuite/libgomp.fortran/cancel-sections-1.f90: New test.
+ * testsuite/libgomp.fortran/cancel-taskgroup-2.f90: New test.
+ * testsuite/libgomp.fortran/declare-simd-1.f90: New test.
+ * testsuite/libgomp.fortran/declare-simd-2.f90: New test.
+ * testsuite/libgomp.fortran/declare-simd-3.f90: New test.
+ * testsuite/libgomp.fortran/depend-1.f90: New test.
+ * testsuite/libgomp.fortran/depend-2.f90: New test.
+ * testsuite/libgomp.fortran/omp_atomic5.f90: New test.
+ * testsuite/libgomp.fortran/simd1.f90: New test.
+ * testsuite/libgomp.fortran/simd2.f90: New test.
+ * testsuite/libgomp.fortran/simd3.f90: New test.
+ * testsuite/libgomp.fortran/simd4.f90: New test.
+ * testsuite/libgomp.fortran/taskgroup1.f90: New test.
+
2014-06-24 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c/for-2.c: Define SC to static for
diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in
index dda297a1d4e..757053c9fbc 100644
--- a/libgomp/omp_lib.f90.in
+++ b/libgomp/omp_lib.f90.in
@@ -42,7 +42,7 @@
module omp_lib
use omp_lib_kinds
implicit none
- integer, parameter :: openmp_version = 201107
+ integer, parameter :: openmp_version = 201307
interface
subroutine omp_init_lock (svar)
diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in
index 7725396ac50..691adb8655f 100644
--- a/libgomp/omp_lib.h.in
+++ b/libgomp/omp_lib.h.in
@@ -45,7 +45,7 @@
parameter (omp_proc_bind_master = 2)
parameter (omp_proc_bind_close = 3)
parameter (omp_proc_bind_spread = 4)
- parameter (openmp_version = 201107)
+ parameter (openmp_version = 201307)
external omp_init_lock, omp_init_nest_lock
external omp_destroy_lock, omp_destroy_nest_lock
diff --git a/libgomp/testsuite/libgomp.c/target-8.c b/libgomp/testsuite/libgomp.c/target-8.c
new file mode 100644
index 00000000000..35084575324
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/target-8.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-fopenmp" } */
+
+void
+foo (int *p)
+{
+ int i;
+ #pragma omp parallel
+ #pragma omp single
+ #pragma omp target teams distribute parallel for map(p[0:24])
+ for (i = 0; i < 24; i++)
+ p[i] = p[i] + 1;
+}
+
+int
+main ()
+{
+ int p[24], i;
+ for (i = 0; i < 24; i++)
+ p[i] = i;
+ foo (p);
+ for (i = 0; i < 24; i++)
+ if (p[i] != i + 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.fortran/aligned1.f03 b/libgomp/testsuite/libgomp.fortran/aligned1.f03
new file mode 100644
index 00000000000..67a9ab40423
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/aligned1.f03
@@ -0,0 +1,133 @@
+! { dg-do run }
+! { dg-options "-fopenmp -fcray-pointer" }
+
+ use iso_c_binding, only : c_ptr, c_ptrdiff_t, c_loc
+ interface
+ subroutine foo (x, y, z, w)
+ use iso_c_binding, only : c_ptr
+ real, pointer :: x(:), y(:), w(:)
+ type(c_ptr) :: z
+ end subroutine
+ subroutine bar (x, y, z, w)
+ use iso_c_binding, only : c_ptr
+ real, pointer :: x(:), y(:), w(:)
+ type(c_ptr) :: z
+ end subroutine
+ subroutine baz (x, c)
+ real, pointer :: x(:)
+ real, allocatable :: c(:)
+ end subroutine
+ end interface
+ type dt
+ real, allocatable :: a(:)
+ end type
+ type (dt) :: b(64)
+ real, target :: a(4096+63)
+ real, pointer :: p(:), q(:), r(:), s(:)
+ real, allocatable :: c(:)
+ integer(c_ptrdiff_t) :: o
+ integer :: i
+ o = 64 - mod (loc (a), 64)
+ if (o == 64) o = 0
+ o = o / sizeof(0.0)
+ p => a(o + 1:o + 1024)
+ q => a(o + 1025:o + 2048)
+ r => a(o + 2049:o + 3072)
+ s => a(o + 3073:o + 4096)
+ do i = 1, 1024
+ p(i) = i
+ q(i) = i
+ r(i) = i
+ s(i) = i
+ end do
+ call foo (p, q, c_loc (r(1)), s)
+ do i = 1, 1024
+ if (p(i) /= i * i + 3 * i + 2) call abort
+ p(i) = i
+ end do
+ call bar (p, q, c_loc (r(1)), s)
+ do i = 1, 1024
+ if (p(i) /= i * i + 3 * i + 2) call abort
+ end do
+ ! Attempt to create 64-byte aligned allocatable
+ do i = 1, 64
+ allocate (c(1023 + i))
+ if (iand (loc (c(1)), 63) == 0) exit
+ deallocate (c)
+ allocate (b(i)%a(1023 + i))
+ allocate (c(1023 + i))
+ if (iand (loc (c(1)), 63) == 0) exit
+ deallocate (c)
+ end do
+ if (allocated (c)) then
+ do i = 1, 1024
+ c(i) = 2 * i
+ end do
+ call baz (p, c)
+ do i = 1, 1024
+ if (p(i) /= i * i + 5 * i + 2) call abort
+ end do
+ end if
+end
+subroutine foo (x, y, z, w)
+ use iso_c_binding, only : c_ptr, c_f_pointer
+ real, pointer :: x(:), y(:), w(:), p(:)
+ type(c_ptr) :: z
+ integer :: i
+ real :: pt(1024)
+ pointer (ip, pt)
+ ip = loc (w)
+!$omp simd aligned (x, y : 64)
+ do i = 1, 1024
+ x(i) = x(i) * y(i) + 2.0
+ end do
+!$omp simd aligned (x, z : 64) private (p)
+ do i = 1, 1024
+ call c_f_pointer (z, p, shape=[1024])
+ x(i) = x(i) + p(i)
+ end do
+!$omp simd aligned (x, ip : 64)
+ do i = 1, 1024
+ x(i) = x(i) + 2 * pt(i)
+ end do
+!$omp end simd
+end subroutine
+subroutine bar (x, y, z, w)
+ use iso_c_binding, only : c_ptr, c_f_pointer
+ real, pointer :: x(:), y(:), w(:), a(:), b(:)
+ type(c_ptr) :: z, c
+ integer :: i
+ real :: pt(1024)
+ pointer (ip, pt)
+ ip = loc (w)
+ a => x
+ b => y
+ c = z
+!$omp simd aligned (a, b : 64)
+ do i = 1, 1024
+ a(i) = a(i) * b(i) + 2.0
+ end do
+!$omp simd aligned (a, c : 64)
+ do i = 1, 1024
+ block
+ real, pointer :: p(:)
+ call c_f_pointer (c, p, shape=[1024])
+ a(i) = a(i) + p(i)
+ end block
+ end do
+!$omp simd aligned (a, ip : 64)
+ do i = 1, 1024
+ a(i) = a(i) + 2 * pt(i)
+ end do
+!$omp end simd
+end subroutine
+subroutine baz (x, c)
+ real, pointer :: x(:)
+ real, allocatable :: c(:)
+ integer :: i
+!$omp simd aligned (x, c : 64)
+ do i = 1, 1024
+ x(i) = x(i) + c(i)
+ end do
+!$omp end simd
+end subroutine baz
diff --git a/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90 b/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90
new file mode 100644
index 00000000000..2a2a12ec817
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90
@@ -0,0 +1,328 @@
+! { dg-do run }
+! Don't cycle by default through all options, just test -O0 and -O2,
+! as this is quite large test.
+! { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } }
+
+module m
+ type dl
+ integer :: a, b
+ integer, allocatable :: c(:,:)
+ integer :: d, e
+ integer, allocatable :: f
+ end type
+ type dt
+ integer :: g
+ type (dl), allocatable :: h(:)
+ integer :: i
+ type (dl) :: j(2, 2)
+ type (dl), allocatable :: k
+ end type
+contains
+ subroutine ver_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
+ type (dl), intent (in) :: obj
+ integer, intent (in) :: val, cl1, cu1, cl2, cu2
+ logical, intent (in) :: c, f
+ if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) call abort
+ if (c) then
+ if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) call abort
+ if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) call abort
+ end if
+ if (val /= 0) then
+ if (obj%a /= val .or. obj%b /= val) call abort
+ if (obj%d /= val .or. obj%e /= val) call abort
+ if (c) then
+ if (any (obj%c /= val)) call abort
+ end if
+ if (f) then
+ if (obj%f /= val) call abort
+ end if
+ end if
+ end subroutine ver_dl
+ subroutine ver_dt (obj, val, h, hl, hu, k, c, cl1, cu1, cl2, cu2, f)
+ type (dt), intent (in) :: obj
+ integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
+ logical, intent (in) :: h, k, c, f
+ integer :: i, j
+ if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) call abort
+ if (h) then
+ if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) call abort
+ do i = hl, hu
+ call ver_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end if
+ do i = 1, 2
+ do j = 1, 2
+ call ver_dl (obj%j(i, j), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end do
+ if (k) call ver_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
+ if (val /= 0) then
+ if (obj%g /= val .or. obj%i /= val) call abort
+ end if
+ end subroutine ver_dt
+ subroutine alloc_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
+ type (dl), intent (inout) :: obj
+ integer, intent (in) :: val, cl1, cu1, cl2, cu2
+ logical, intent (in) :: c, f
+ if (val /= 0) then
+ obj%a = val
+ obj%b = val
+ obj%d = val
+ obj%e = val
+ end if
+ if (allocated (obj%c)) deallocate (obj%c)
+ if (c) then
+ allocate (obj%c(cl1:cu1, cl2:cu2))
+ if (val /= 0) obj%c = val
+ end if
+ if (f) then
+ if (.not.allocated (obj%f)) allocate (obj%f)
+ if (val /= 0) obj%f = val
+ else
+ if (allocated (obj%f)) deallocate (obj%f)
+ end if
+ end subroutine alloc_dl
+ subroutine alloc_dt (obj, val, h, hl, hu, k, c, cl1, cu1, cl2, cu2, f)
+ type (dt), intent (inout) :: obj
+ integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
+ logical, intent (in) :: h, k, c, f
+ integer :: i, j
+ if (val /= 0) then
+ obj%g = val
+ obj%i = val
+ end if
+ if (allocated (obj%h)) deallocate (obj%h)
+ if (h) then
+ allocate (obj%h(hl:hu))
+ do i = hl, hu
+ call alloc_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end if
+ do i = 1, 2
+ do j = 1, 2
+ call alloc_dl (obj%j(i, j), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end do
+ if (k) then
+ if (.not.allocated (obj%k)) allocate (obj%k)
+ call alloc_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
+ else
+ if (allocated (obj%k)) deallocate (obj%k)
+ end if
+ end subroutine alloc_dt
+end module m
+ use m
+ type (dt) :: y
+ call foo (y)
+contains
+ subroutine foo (y)
+ use m
+ type (dt) :: x, y, z(-3:-3,2:3)
+ logical, parameter :: F = .false.
+ logical, parameter :: T = .true.
+ logical :: l
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel private (x, y, z)
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (y, 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+!$omp end parallel
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+!$omp parallel private (x, y, z)
+ call ver_dt (x, 0, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 0, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ deallocate (x%h, x%k)
+ deallocate (y%h)
+ allocate (y%k)
+ call ver_dt (z(-3,2), 0, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ deallocate (z(-3,2)%h, z(-3,2)%k)
+ deallocate (z(-3,3)%h)
+ allocate (z(-3,3)%k)
+!$omp end parallel
+ call alloc_dt (x, 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (y, 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+!$omp parallel firstprivate (x, y, z)
+ call ver_dt (x, 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (y, 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (y, 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,3), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,3), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+!$omp end parallel
+ call ver_dt (x, 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (x, 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (y, 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel firstprivate (x, y, z)
+ call ver_dt (x, 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (y, 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (z(-3,3), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+!$omp end parallel
+ call ver_dt (x, 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 18, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 18, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ l = F
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (l) then
+ call ver_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ else
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ end if
+ l = T
+ call alloc_dt (x, 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (x, 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call alloc_dt (y, 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (y, 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call alloc_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call alloc_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+!$omp section
+ if (l) then
+ call ver_dt (x, 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (y, 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ else
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ end if
+ l = T
+ call alloc_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call alloc_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call alloc_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call alloc_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+!$omp section
+!$omp end parallel sections
+ call ver_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (l) then
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ else
+ call ver_dt (x, 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ end if
+ l = T
+ call alloc_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call alloc_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp section
+ if (l) then
+ call ver_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ else
+ call ver_dt (x, 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ end if
+ l = T
+ call alloc_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call alloc_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp section
+!$omp end parallel sections
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp parallel private (x, y, z)
+ call ver_dt (x, 0, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 0, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 0, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp single
+ call alloc_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call alloc_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp end single copyprivate (x, y, z)
+ call ver_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp end parallel
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ end subroutine foo
+end
diff --git a/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90 b/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90
new file mode 100644
index 00000000000..490ed24cf4f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90
@@ -0,0 +1,367 @@
+! { dg-do run }
+! Don't cycle by default through all options, just test -O0 and -O2,
+! as this is quite large test.
+! { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } }
+
+module m
+ type dl
+ integer :: a, b
+ integer, allocatable :: c(:,:)
+ integer :: d, e
+ integer, allocatable :: f
+ end type
+ type dt
+ integer :: g
+ type (dl), allocatable :: h(:)
+ integer :: i
+ type (dl) :: j(2, 2)
+ type (dl), allocatable :: k
+ end type
+contains
+ subroutine ver_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
+ type (dl), intent (in) :: obj
+ integer, intent (in) :: val, cl1, cu1, cl2, cu2
+ logical, intent (in) :: c, f
+ if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) call abort
+ if (c) then
+ if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) call abort
+ if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) call abort
+ end if
+ if (val /= 0) then
+ if (obj%a /= val .or. obj%b /= val) call abort
+ if (obj%d /= val .or. obj%e /= val) call abort
+ if (c) then
+ if (any (obj%c /= val)) call abort
+ end if
+ if (f) then
+ if (obj%f /= val) call abort
+ end if
+ end if
+ end subroutine ver_dl
+ subroutine ver_dt (obj, val, h, hl, hu, k, c, cl1, cu1, cl2, cu2, f)
+ type (dt), intent (in) :: obj
+ integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
+ logical, intent (in) :: h, k, c, f
+ integer :: i, j
+ if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) call abort
+ if (h) then
+ if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) call abort
+ do i = hl, hu
+ call ver_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end if
+ do i = 1, 2
+ do j = 1, 2
+ call ver_dl (obj%j(i, j), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end do
+ if (k) call ver_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
+ if (val /= 0) then
+ if (obj%g /= val .or. obj%i /= val) call abort
+ end if
+ end subroutine ver_dt
+ subroutine alloc_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
+ type (dl), intent (inout) :: obj
+ integer, intent (in) :: val, cl1, cu1, cl2, cu2
+ logical, intent (in) :: c, f
+ if (val /= 0) then
+ obj%a = val
+ obj%b = val
+ obj%d = val
+ obj%e = val
+ end if
+ if (allocated (obj%c)) deallocate (obj%c)
+ if (c) then
+ allocate (obj%c(cl1:cu1, cl2:cu2))
+ if (val /= 0) obj%c = val
+ end if
+ if (f) then
+ if (.not.allocated (obj%f)) allocate (obj%f)
+ if (val /= 0) obj%f = val
+ else
+ if (allocated (obj%f)) deallocate (obj%f)
+ end if
+ end subroutine alloc_dl
+ subroutine alloc_dt (obj, val, h, hl, hu, k, c, cl1, cu1, cl2, cu2, f)
+ type (dt), intent (inout) :: obj
+ integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
+ logical, intent (in) :: h, k, c, f
+ integer :: i, j
+ if (val /= 0) then
+ obj%g = val
+ obj%i = val
+ end if
+ if (allocated (obj%h)) deallocate (obj%h)
+ if (h) then
+ allocate (obj%h(hl:hu))
+ do i = hl, hu
+ call alloc_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end if
+ do i = 1, 2
+ do j = 1, 2
+ call alloc_dl (obj%j(i, j), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end do
+ if (k) then
+ if (.not.allocated (obj%k)) allocate (obj%k)
+ call alloc_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
+ else
+ if (allocated (obj%k)) deallocate (obj%k)
+ end if
+ end subroutine alloc_dt
+end module m
+ use m
+ type (dt), allocatable :: y
+ call foo (y)
+contains
+ subroutine foo (y)
+ use m
+ type (dt), allocatable :: x, y, z(:,:)
+ logical, parameter :: F = .false.
+ logical, parameter :: T = .true.
+ logical :: l
+!$omp parallel private (x, y, z)
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) call abort
+!$omp end parallel
+!$omp parallel firstprivate (x, y, z)
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) call abort
+!$omp end parallel
+ l = F
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (.not. l) then
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) call abort
+ end if
+!$omp section
+ if (.not. l) then
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) call abort
+ end if
+ allocate (x, y, z(-3:-3,2:3))
+ call alloc_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call alloc_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp section
+!$omp end parallel sections
+ if (.not.allocated (x) .or. .not.allocated (y)) call abort
+ if (.not.allocated (z)) call abort
+ if (lbound (z, 1) /= -3 .or. ubound (z, 1) /= -3) call abort
+ if (lbound (z, 2) /= 2 .or. ubound (z, 2) /= 3) call abort
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call alloc_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel private (x, y, z)
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (y, 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+!$omp end parallel
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+!$omp parallel private (x, y, z)
+ call ver_dt (x, 0, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 0, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ deallocate (x%h, x%k)
+ deallocate (y%h)
+ allocate (y%k)
+ call ver_dt (z(-3,2), 0, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ deallocate (z(-3,2)%h, z(-3,2)%k)
+ deallocate (z(-3,3)%h)
+ allocate (z(-3,3)%k)
+!$omp end parallel
+ call alloc_dt (x, 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (y, 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+!$omp parallel firstprivate (x, y, z)
+ call ver_dt (x, 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (y, 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (y, 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,3), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,3), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+!$omp end parallel
+ call ver_dt (x, 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (x, 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (y, 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel firstprivate (x, y, z)
+ call ver_dt (x, 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x, 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y, 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (y, 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (z(-3,3), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+!$omp end parallel
+ call ver_dt (x, 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y, 18, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 18, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ l = F
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (l) then
+ call ver_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ else
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ end if
+ l = T
+ call alloc_dt (x, 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (x, 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call alloc_dt (y, 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (y, 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call alloc_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call alloc_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+!$omp section
+ if (l) then
+ call ver_dt (x, 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (y, 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ else
+ call ver_dt (x, 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y, 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ end if
+ l = T
+ call alloc_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call alloc_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call alloc_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call alloc_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+!$omp section
+!$omp end parallel sections
+ call ver_dt (x, 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (l) then
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ else
+ call ver_dt (x, 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ end if
+ l = T
+ call alloc_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call alloc_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp section
+ if (l) then
+ call ver_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ else
+ call ver_dt (x, 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y, 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ end if
+ l = T
+ call alloc_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call alloc_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp section
+!$omp end parallel sections
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp parallel private (x, y, z)
+ call ver_dt (x, 0, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 0, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 0, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp single
+ call alloc_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call alloc_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp end single copyprivate (x, y, z)
+ call ver_dt (x, 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (y, 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp end parallel
+ call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ end subroutine foo
+end
diff --git a/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90 b/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90
new file mode 100644
index 00000000000..20f13144a62
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90
@@ -0,0 +1,372 @@
+! { dg-do run }
+! Don't cycle by default through all options, just test -O0 and -O2,
+! as this is quite large test.
+! { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } }
+
+module m
+ type dl
+ integer :: a, b
+ integer, allocatable :: c(:,:)
+ integer :: d, e
+ integer, allocatable :: f
+ end type
+ type dt
+ integer :: g
+ type (dl), allocatable :: h(:)
+ integer :: i
+ type (dl) :: j(2, 2)
+ type (dl), allocatable :: k
+ end type
+contains
+ subroutine ver_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
+ type (dl), intent (in) :: obj
+ integer, intent (in) :: val, cl1, cu1, cl2, cu2
+ logical, intent (in) :: c, f
+ if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) call abort
+ if (c) then
+ if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) call abort
+ if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) call abort
+ end if
+ if (val /= 0) then
+ if (obj%a /= val .or. obj%b /= val) call abort
+ if (obj%d /= val .or. obj%e /= val) call abort
+ if (c) then
+ if (any (obj%c /= val)) call abort
+ end if
+ if (f) then
+ if (obj%f /= val) call abort
+ end if
+ end if
+ end subroutine ver_dl
+ subroutine ver_dt (obj, val, h, hl, hu, k, c, cl1, cu1, cl2, cu2, f)
+ type (dt), intent (in) :: obj
+ integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
+ logical, intent (in) :: h, k, c, f
+ integer :: i, j
+ if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) call abort
+ if (h) then
+ if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) call abort
+ do i = hl, hu
+ call ver_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end if
+ do i = 1, 2
+ do j = 1, 2
+ call ver_dl (obj%j(i, j), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end do
+ if (k) call ver_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
+ if (val /= 0) then
+ if (obj%g /= val .or. obj%i /= val) call abort
+ end if
+ end subroutine ver_dt
+ subroutine alloc_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
+ type (dl), intent (inout) :: obj
+ integer, intent (in) :: val, cl1, cu1, cl2, cu2
+ logical, intent (in) :: c, f
+ if (val /= 0) then
+ obj%a = val
+ obj%b = val
+ obj%d = val
+ obj%e = val
+ end if
+ if (allocated (obj%c)) deallocate (obj%c)
+ if (c) then
+ allocate (obj%c(cl1:cu1, cl2:cu2))
+ if (val /= 0) obj%c = val
+ end if
+ if (f) then
+ if (.not.allocated (obj%f)) allocate (obj%f)
+ if (val /= 0) obj%f = val
+ else
+ if (allocated (obj%f)) deallocate (obj%f)
+ end if
+ end subroutine alloc_dl
+ subroutine alloc_dt (obj, val, h, hl, hu, k, c, cl1, cu1, cl2, cu2, f)
+ type (dt), intent (inout) :: obj
+ integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
+ logical, intent (in) :: h, k, c, f
+ integer :: i, j
+ if (val /= 0) then
+ obj%g = val
+ obj%i = val
+ end if
+ if (allocated (obj%h)) deallocate (obj%h)
+ if (h) then
+ allocate (obj%h(hl:hu))
+ do i = hl, hu
+ call alloc_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end if
+ do i = 1, 2
+ do j = 1, 2
+ call alloc_dl (obj%j(i, j), val, c, cl1, cu1, cl2, cu2, f)
+ end do
+ end do
+ if (k) then
+ if (.not.allocated (obj%k)) allocate (obj%k)
+ call alloc_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
+ else
+ if (allocated (obj%k)) deallocate (obj%k)
+ end if
+ end subroutine alloc_dt
+end module m
+ use m
+ type (dt), allocatable :: z(:,:)
+ type (dt) :: y(2:3)
+ call foo (y, z, 4)
+contains
+ subroutine foo (y, z, n)
+ use m
+ integer :: n
+ type (dt) :: x(2:n), y(3:)
+ type (dt), allocatable :: z(:,:)
+ logical, parameter :: F = .false.
+ logical, parameter :: T = .true.
+ logical :: l
+ if (lbound (x, 1) /= 2 .or. ubound (x, 1) /= 4) call abort
+ if (lbound (y, 1) /= 3 .or. ubound (y, 1) /= 4) call abort
+ call ver_dt (x(2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (x(n), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(4), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel private (z)
+ if (allocated (z)) call abort
+!$omp end parallel
+!$omp parallel firstprivate (z)
+ if (allocated (z)) call abort
+!$omp end parallel
+ l = F
+!$omp parallel sections lastprivate (z) firstprivate (l)
+!$omp section
+ if (.not. l) then
+ if (allocated (z)) call abort
+ end if
+!$omp section
+ if (.not. l) then
+ if (allocated (z)) call abort
+ end if
+ allocate (z(-3:-3,2:3))
+ call alloc_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp section
+!$omp end parallel sections
+ if (.not.allocated (z)) call abort
+ if (lbound (z, 1) /= -3 .or. ubound (z, 1) /= -3) call abort
+ if (lbound (z, 2) /= 2 .or. ubound (z, 2) /= 3) call abort
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (x(n - 1), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(4), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel private (x, y, z)
+ call ver_dt (x(n - 1), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y(4), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y(4), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (y(4), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+!$omp end parallel
+ call ver_dt (x(n - 1), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y(4), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y(4), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 14, T, 3, 4, F, T, 1, 1, 2, 4, T)
+!$omp parallel private (x, y, z)
+ call ver_dt (x(n - 1), 0, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y(4), 0, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ deallocate (x(n - 1)%h, x(n - 1)%k)
+ deallocate (y(4)%h)
+ allocate (y(4)%k)
+ call ver_dt (z(-3,2), 0, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 0, T, 3, 4, F, T, 1, 1, 2, 4, T)
+ deallocate (z(-3,2)%h, z(-3,2)%k)
+ deallocate (z(-3,3)%h)
+ allocate (z(-3,3)%k)
+!$omp end parallel
+ call alloc_dt (x(n - 1), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (y(4), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+!$omp parallel firstprivate (x, y, z)
+ if (lbound (x, 1) /= 2 .or. ubound (x, 1) /= 4) call abort
+ if (lbound (y, 1) /= 3 .or. ubound (y, 1) /= 4) call abort
+ call ver_dt (x(n - 1), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y(4), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (y(4), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (y(4), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,3), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+ call ver_dt (z(-3,3), 4, T, 3, 4, T, T, 1, 1, 2, 4, T)
+!$omp end parallel
+ call ver_dt (x(n - 1), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (x(n - 1), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(4), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (y(4), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
+ call alloc_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
+ call alloc_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+!$omp parallel firstprivate (x, y, z)
+ call ver_dt (x(n - 1), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (y(4), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y(4), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (y(4), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,2), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
+ call ver_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+ call ver_dt (z(-3,3), 17, T, 1, 2, F, T, 2, 2, 3, 3, F)
+!$omp end parallel
+ call ver_dt (x(n - 1), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(4), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (y(4), 18, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 4, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 16, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call alloc_dt (z(-3,3), 18, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ l = F
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (l) then
+ call ver_dt (x(n - 1), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y(4), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ else
+ call ver_dt (x(n - 1), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(4), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ end if
+ l = T
+ call alloc_dt (x(n - 1), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (x(n - 1), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call alloc_dt (y(4), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (y(4), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call alloc_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call alloc_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+!$omp section
+ if (l) then
+ call ver_dt (x(n - 1), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (y(4), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ call ver_dt (z(-3,2), 7, T, 1, 1, T, T, 1, 2, 3, 3, T)
+ call ver_dt (z(-3,3), 20, T, 0, 0, F, T, 2, 2, 3, 4, F)
+ else
+ call ver_dt (x(n - 1), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(4), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ call ver_dt (z(-3,2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 0, 1, 0, 1, T)
+ end if
+ l = T
+ call alloc_dt (x(n - 1), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (x(n - 1), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call alloc_dt (y(4), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (y(4), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call alloc_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call alloc_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+!$omp section
+!$omp end parallel sections
+ call ver_dt (x(n - 1), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y(4), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 9, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 21, F, 0, 0, T, T, 1, 2, 3, 4, T)
+!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
+!$omp section
+ if (l) then
+ call ver_dt (x(n - 1), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y(4), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ else
+ call ver_dt (x(n - 1), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y(4), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ end if
+ l = T
+ call alloc_dt (x(n - 1), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (x(n - 1), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (y(4), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (y(4), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call alloc_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp section
+ if (l) then
+ call ver_dt (x(n - 1), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (y(4), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ else
+ call ver_dt (x(n - 1), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (y(4), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ call ver_dt (z(-3,2), 0, T, 1, 1, F, F, 0, 0, 0, 0, T)
+ call ver_dt (z(-3,3), 0, F, 0, 0, T, T, 1, 2, 3, 4, T)
+ end if
+ l = T
+ call alloc_dt (x(n - 1), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (x(n - 1), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (y(4), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (y(4), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call alloc_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call alloc_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp section
+!$omp end parallel sections
+ call ver_dt (x(n - 1), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y(4), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp parallel private (x, y, z)
+ call ver_dt (x(n - 1), 0, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y(4), 0, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 0, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 0, T, 0, 1, T, T, 2, 2, 2, 2, F)
+!$omp single
+ call alloc_dt (x(n - 1), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (y(4), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call alloc_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call alloc_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp end single copyprivate (x, y, z)
+ call ver_dt (x(n - 1), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (y(4), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+ call ver_dt (z(-3,2), 3, F, 0, 0, T, T, 0, 1, 0, 1, F)
+ call ver_dt (z(-3,3), 22, T, 5, 5, F, T, 2, 3, 2, 2, T)
+!$omp end parallel
+ call ver_dt (x(n - 1), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (y(4), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
+ call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
+ call ver_dt (x(2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (x(n), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ call ver_dt (y(3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
+ end subroutine foo
+end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable10.f90 b/libgomp/testsuite/libgomp.fortran/allocatable10.f90
new file mode 100644
index 00000000000..54eed617b45
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable10.f90
@@ -0,0 +1,112 @@
+! { dg-do run }
+
+ integer, allocatable :: a, b(:), c(:,:)
+ integer :: i
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in) &
+!$omp & initializer (omp_priv = 0)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(6:9), c(3, 8:9))
+ a = 0
+ b = 0
+ c = 0
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+!$omp parallel do reduction (+:a, b, c)
+ do i = 1, 10
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ a = a + i
+ b = b + 2 * i
+ c = c + 3 * i
+ end do
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) call abort
+ a = 0
+ b = 0
+ c = 0
+!$omp parallel do reduction (foo : a, b, c)
+ do i = 1, 10
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ a = a + i
+ b = b + 2 * i
+ c = c + 3 * i
+ end do
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) call abort
+ a = 0
+ b = 0
+ c = 0
+!$omp simd reduction (+:a, b, c)
+ do i = 1, 10
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ a = a + i
+ b = b + 2 * i
+ c = c + 3 * i
+ end do
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) call abort
+ a = 0
+ b = 0
+ c = 0
+!$omp simd reduction (foo : a, b, c)
+ do i = 1, 10
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ a = a + i
+ b = b + 2 * i
+ c = c + 3 * i
+ end do
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable11.f90 b/libgomp/testsuite/libgomp.fortran/allocatable11.f90
new file mode 100644
index 00000000000..479f6041b7d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable11.f90
@@ -0,0 +1,72 @@
+! { dg-do run }
+! { dg-require-effective-target tls_runtime }
+
+ use omp_lib
+ integer, allocatable, save :: a, b(:), c(:,:)
+ integer :: p
+!$omp threadprivate (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+
+ call omp_set_dynamic (.false.)
+ call omp_set_num_threads (4)
+
+!$omp parallel num_threads (4)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+!$omp end parallel
+
+ allocate (a, b(6:9), c(3, 8:9))
+ a = 4
+ b = 5
+ c = 6
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+
+!$omp parallel num_threads (4) copyin (a, b, c) private (p)
+ p = omp_get_thread_num ()
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 4 .or. any (b /= 5) .or. any (c /= 6)) call abort
+ deallocate (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(p:9), c(3, p:7))
+ a = p
+ b = p
+ c = p
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= (10 - p)) call abort
+ if (lbound (b, 1) /= p .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= (3 * (8 - p))) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= (8 - p)) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= p .or. ubound (c, 2) /= 7) call abort
+ if (a /= p .or. any (b /= p) .or. any (c /= p)) call abort
+!$omp end parallel
+
+!$omp parallel num_threads (4) copyin (a, b, c)
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 10) call abort
+ if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 24) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 8) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 0 .or. ubound (c, 2) /= 7) call abort
+ if (a /= 0 .or. any (b /= 0) .or. any (c /= 0)) call abort
+!$omp end parallel
+
+ deallocate (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+
+!$omp parallel num_threads (4) copyin (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+!$omp end parallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable12.f90 b/libgomp/testsuite/libgomp.fortran/allocatable12.f90
new file mode 100644
index 00000000000..533ab7cd85d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable12.f90
@@ -0,0 +1,74 @@
+! { dg-do run }
+
+ integer, allocatable :: a, b(:), c(:,:)
+ logical :: l
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+
+!$omp parallel private (a, b, c, l)
+ l = .false.
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+
+!$omp single
+ allocate (a, b(6:9), c(3, 8:9))
+ a = 4
+ b = 5
+ c = 6
+!$omp end single copyprivate (a, b, c)
+
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 4 .or. any (b /= 5) .or. any (c /= 6)) call abort
+
+!$omp single
+ deallocate (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(0:4), c(3, 2:7))
+ a = 1
+ b = 2
+ c = 3
+!$omp end single copyprivate (a, b, c)
+
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 5) call abort
+ if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 4) call abort
+ if (.not.allocated (c) .or. size (c) /= 18) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 6) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 2 .or. ubound (c, 2) /= 7) call abort
+ if (a /= 1 .or. any (b /= 2) .or. any (c /= 3)) call abort
+
+!$omp single
+ l = .true.
+ deallocate (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(2:6), c(3:5, 3:8))
+ a = 7
+ b = 8
+ c = 9
+!$omp end single copyprivate (a, b, c)
+
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 5) call abort
+ if (l) then
+ if (lbound (b, 1) /= 2 .or. ubound (b, 1) /= 6) call abort
+ else
+ if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 4) call abort
+ end if
+ if (.not.allocated (c) .or. size (c) /= 18) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 6) call abort
+ if (l) then
+ if (lbound (c, 1) /= 3 .or. ubound (c, 1) /= 5) call abort
+ if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 8) call abort
+ else
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 2 .or. ubound (c, 2) /= 7) call abort
+ end if
+ if (a /= 7 .or. any (b /= 8) .or. any (c /= 9)) call abort
+
+!$omp end parallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable9.f90 b/libgomp/testsuite/libgomp.fortran/allocatable9.f90
new file mode 100644
index 00000000000..80bf5d389f3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable9.f90
@@ -0,0 +1,156 @@
+! { dg-do run }
+
+ integer, allocatable :: a, b(:), c(:,:)
+ logical :: l
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+!$omp parallel private (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(-7:-1), c(2:3, 3:5))
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 7) call abort
+ if (lbound (b, 1) /= -7 .or. ubound (b, 1) /= -1) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 3) call abort
+ if (lbound (c, 1) /= 2 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 5) call abort
+ a = 4
+ b = 3
+ c = 2
+!$omp end parallel
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+!$omp parallel firstprivate (a, b, c)
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(-7:-1), c(2:3, 3:5))
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 7) call abort
+ if (lbound (b, 1) /= -7 .or. ubound (b, 1) /= -1) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 3) call abort
+ if (lbound (c, 1) /= 2 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 5) call abort
+ a = 4
+ b = 3
+ c = 2
+!$omp end parallel
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) call abort
+ allocate (a, b(6:9), c(3, 8:9))
+ a = 2
+ b = 4
+ c = 5
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+!$omp parallel firstprivate (a, b, c)
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 2 .or. any (b .ne. 4) .or. any (c .ne. 5)) call abort
+ deallocate (a)
+ if (allocated (a)) call abort
+ allocate (a)
+ a = 8
+ b = (/ 1, 2, 3 /)
+ c = reshape ((/ 1, 2, 3, 4, 5, 6, 7, 8 /), (/ 2, 4 /))
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 3) call abort
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) call abort
+ if (.not.allocated (c) .or. size (c) /= 8) call abort
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 4) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) call abort
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) call abort
+ if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) call abort
+!$omp end parallel
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ if (a /= 2 .or. any (b .ne. 4) .or. any (c .ne. 5)) call abort
+ l = .false.
+!$omp parallel sections lastprivate (a, b, c) firstprivate (l)
+!$omp section
+ if (.not.allocated (a)) call abort
+ if (l) then
+ if (.not.allocated (b) .or. size (b) /= 6) call abort
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) call abort
+ if (.not.allocated (c) .or. size (c) /= 8) call abort
+ if (size (c, 1) /= 4 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) call abort
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) call abort
+ if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) call abort
+ else
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ end if
+ l = .true.
+ deallocate (a)
+ if (allocated (a)) call abort
+ allocate (a)
+ a = 8
+ b = (/ 1, 2, 3 /)
+ c = reshape ((/ 1, 2, 3, 4, 5, 6, 7, 8 /), (/ 2, 4 /))
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 3) call abort
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) call abort
+ if (.not.allocated (c) .or. size (c) /= 8) call abort
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 4) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) call abort
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) call abort
+ if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) call abort
+!$omp section
+ if (.not.allocated (a)) call abort
+ if (l) then
+ if (.not.allocated (b) .or. size (b) /= 3) call abort
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) call abort
+ if (.not.allocated (c) .or. size (c) /= 8) call abort
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 4) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) call abort
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) call abort
+ if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) call abort
+ else
+ if (.not.allocated (b) .or. size (b) /= 4) call abort
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) call abort
+ if (.not.allocated (c) .or. size (c) /= 6) call abort
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) call abort
+ end if
+ l = .true.
+ deallocate (a)
+ if (allocated (a)) call abort
+ allocate (a)
+ a = 12
+ b = (/ 9, 8, 7, 6, 5, 4 /)
+ c = reshape ((/ 1, 2, 3, 4, 5, 6, 7, 8 /), (/ 4, 2 /))
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 6) call abort
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) call abort
+ if (.not.allocated (c) .or. size (c) /= 8) call abort
+ if (size (c, 1) /= 4 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) call abort
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) call abort
+ if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) call abort
+!$omp end parallel sections
+ if (.not.allocated (a)) call abort
+ if (.not.allocated (b) .or. size (b) /= 6) call abort
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) call abort
+ if (.not.allocated (c) .or. size (c) /= 8) call abort
+ if (size (c, 1) /= 4 .or. size (c, 2) /= 2) call abort
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) call abort
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) call abort
+ if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/associate1.f90 b/libgomp/testsuite/libgomp.fortran/associate1.f90
new file mode 100644
index 00000000000..e40995515d8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/associate1.f90
@@ -0,0 +1,23 @@
+! { dg-do run }
+
+program associate1
+ integer :: v, i, j
+ real :: a(3, 3)
+ v = 15
+ a = 4.5
+ a(2,1) = 3.5
+ i = 2
+ j = 1
+ associate(u => v, b => a(i, j))
+!$omp parallel private(v, a) default(none)
+ v = -1
+ a = 2.5
+ if (v /= -1 .or. u /= 15) call abort
+ if (a(2,1) /= 2.5 .or. b /= 3.5) call abort
+ associate(u => v, b => a(2, 1))
+ if (u /= -1 .or. b /= 2.5) call abort
+ end associate
+ if (u /= 15 .or. b /= 3.5) call abort
+!$omp end parallel
+ end associate
+end program
diff --git a/libgomp/testsuite/libgomp.fortran/associate2.f90 b/libgomp/testsuite/libgomp.fortran/associate2.f90
new file mode 100644
index 00000000000..dee8496e1d7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/associate2.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+
+program associate2
+ type dl
+ integer :: i
+ end type
+ type dt
+ integer :: i
+ real :: a(3, 3)
+ type(dl) :: c(3, 3)
+ end type
+ integer :: v(4), i, j, k, l
+ type (dt) :: a(3, 3)
+ v = 15
+ forall (k = 1:3, l = 1:3) a(k, l)%a(:,:) = 4.5
+ a(2,1)%a(1,2) = 3.5
+ i = 2
+ j = 1
+ associate(u => v, b => a(i, j)%a)
+!$omp parallel private(v, a) default(none)
+ v = -1
+ forall (k = 1:3, l = 1:3) a(k, l)%a(:,:) = 2.5
+ if (v(3) /= -1 .or. u(3) /= 15) call abort
+ if (a(2,1)%a(1,2) /= 2.5 .or. b(1,2) /= 3.5) call abort
+ associate(u => v, b => a(2, 1)%a)
+ if (u(3) /= -1 .or. b(1,2) /= 2.5) call abort
+ end associate
+ if (u(3) /= 15 .or. b(1,2) /= 3.5) call abort
+!$omp end parallel
+ end associate
+ forall (k = 1:3, l = 1:3) a(k, l)%c(:,:)%i = 7
+ a(1,2)%c(2,1)%i = 9
+ i = 1
+ j = 2
+ associate(d => a(i, j)%c(2,:)%i)
+!$omp parallel private(a) default(none)
+ forall (k = 1:3, l = 1:3) a(k, l)%c(:,:)%i = 15
+ if (a(1,2)%c(2,1)%i /= 15 .or. d(1) /= 9) call abort
+ if (a(1,2)%c(2,2)%i /= 15 .or. d(2) /= 7) call abort
+ associate(d => a(2,1)%c(2,:)%i)
+ if (d(1) /= 15 .or. d(2) /= 15) call abort
+ end associate
+ if (d(1) /= 9 .or. d(2) /= 7) call abort
+!$omp end parallel
+ end associate
+end program
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90 b/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90
new file mode 100644
index 00000000000..61713c4dd94
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90
@@ -0,0 +1,14 @@
+! { dg-do run }
+! { dg-set-target-env-var OMP_CANCELLATION "true" }
+
+ use omp_lib
+ integer :: i
+
+ !$omp parallel num_threads(32)
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do
+ if (omp_get_cancellation ()) call abort
+ enddo
+ !$omp endparallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90 b/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90
new file mode 100644
index 00000000000..c748800cad5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90
@@ -0,0 +1,90 @@
+! { dg-do run }
+! { dg-options "-fno-inline -fno-ipa-sra -fno-ipa-cp -fno-ipa-cp-clone" }
+! { dg-set-target-env-var OMP_CANCELLATION "true" }
+
+ use omp_lib
+ integer :: i
+ logical :: x(5)
+
+ x(:) = .false.
+ x(1) = .true.
+ x(3) = .true.
+ if (omp_get_cancellation ()) call foo (x)
+contains
+ subroutine foo (x)
+ use omp_lib
+ logical :: x(5)
+ integer :: v, w, i
+
+ v = 0
+ w = 0
+ !$omp parallel num_threads (32) shared (v, w)
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(1))
+ call abort
+ end do
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(2))
+ !$omp atomic
+ v = v + 1
+ !$omp endatomic
+ enddo
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(3))
+ !$omp atomic
+ w = w + 8
+ !$omp end atomic
+ end do
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(4))
+ !$omp atomic
+ v = v + 2
+ !$omp end atomic
+ end do
+ !$omp end do
+ !$omp end parallel
+ if (v.ne.3000.or.w.ne.0) call abort
+ !$omp parallel num_threads (32) shared (v, w)
+ ! None of these cancel directives should actually cancel anything,
+ ! but the compiler shouldn't know that and thus should use cancellable
+ ! barriers at the end of all the workshares.
+ !$omp cancel parallel if (omp_get_thread_num ().eq.1.and.x(5))
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(1))
+ call abort
+ end do
+ !$omp cancel parallel if (omp_get_thread_num ().eq.2.and.x(5))
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(2))
+ !$omp atomic
+ v = v + 1
+ !$omp endatomic
+ enddo
+ !$omp cancel parallel if (omp_get_thread_num ().eq.3.and.x(5))
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(3))
+ !$omp atomic
+ w = w + 8
+ !$omp end atomic
+ end do
+ !$omp cancel parallel if (omp_get_thread_num ().eq.4.and.x(5))
+ !$omp do
+ do i = 0, 999
+ !$omp cancel do if (x(4))
+ !$omp atomic
+ v = v + 2
+ !$omp end atomic
+ end do
+ !$omp end do
+ !$omp cancel parallel if (omp_get_thread_num ().eq.5.and.x(5))
+ !$omp end parallel
+ if (v.ne.6000.or.w.ne.0) call abort
+ end subroutine
+end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90 b/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90
new file mode 100644
index 00000000000..7d91ff5c169
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90
@@ -0,0 +1,10 @@
+! { dg-do run }
+! { dg-set-target-env-var OMP_CANCELLATION "true" }
+
+ use omp_lib
+
+ !$omp parallel num_threads(32)
+ !$omp cancel parallel
+ if (omp_get_cancellation ()) call abort
+ !$omp end parallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-parallel-3.f90 b/libgomp/testsuite/libgomp.fortran/cancel-parallel-3.f90
new file mode 100644
index 00000000000..9d5ba8ffa38
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/cancel-parallel-3.f90
@@ -0,0 +1,38 @@
+! { dg-do run }
+! { dg-options "-fno-inline -fno-ipa-sra -fno-ipa-cp -fno-ipa-cp-clone" }
+! { dg-set-target-env-var OMP_CANCELLATION "true" }
+
+ use omp_lib
+ integer :: x, i, j
+ common /x/ x
+
+ call omp_set_dynamic (.false.)
+ call omp_set_schedule (omp_sched_static, 1)
+ !$omp parallel num_threads(16) private (i, j)
+ call do_some_work
+ !$omp barrier
+ if (omp_get_thread_num ().eq.1) then
+ call sleep (2)
+ !$omp cancellation point parallel
+ end if
+ do j = 3, 16
+ !$omp do schedule(runtime)
+ do i = 0, j - 1
+ call do_some_work
+ end do
+ !$omp enddo nowait
+ end do
+ if (omp_get_thread_num ().eq.0) then
+ call sleep (1)
+ !$omp cancel parallel
+ end if
+ !$omp end parallel
+contains
+ subroutine do_some_work
+ integer :: x
+ common /x/ x
+ !$omp atomic
+ x = x + 1
+ !$omp end atomic
+ endsubroutine do_some_work
+end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90 b/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90
new file mode 100644
index 00000000000..9ba8af84679
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90
@@ -0,0 +1,23 @@
+! { dg-do run }
+! { dg-set-target-env-var OMP_CANCELLATION "true" }
+
+ use omp_lib
+
+ if (omp_get_cancellation ()) then
+ !$omp parallel num_threads(32)
+ !$omp sections
+ !$omp cancel sections
+ call abort
+ !$omp section
+ !$omp cancel sections
+ call abort
+ !$omp section
+ !$omp cancel sections
+ call abort
+ !$omp section
+ !$omp cancel sections
+ call abort
+ !$omp end sections
+ !$omp end parallel
+ end if
+end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90 b/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90
new file mode 100644
index 00000000000..c727a20ae41
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+! { dg-set-target-env-var OMP_CANCELLATION "true" }
+
+ use omp_lib
+ integer :: i
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp task
+ !$omp cancel taskgroup
+ call abort
+ !$omp endtask
+ !$omp endtaskgroup
+ !$omp endparallel
+ !$omp parallel private (i)
+ !$omp barrier
+ !$omp single
+ !$omp taskgroup
+ do i = 0, 49
+ !$omp task
+ !$omp cancellation point taskgroup
+ !$omp cancel taskgroup if (i.gt.5)
+ !$omp end task
+ end do
+ !$omp end taskgroup
+ !$omp endsingle
+ !$omp end parallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90 b/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90
new file mode 100644
index 00000000000..5cd592c09db
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90
@@ -0,0 +1,95 @@
+! { dg-do run { target vect_simd_clones } }
+! { dg-options "-fno-inline" }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+module declare_simd_1_mod
+ contains
+ real function foo (a, b, c)
+ !$omp declare simd (foo) simdlen (4) uniform (a) linear (b : 5) &
+ !$omp & notinbranch
+ double precision, value :: a
+ real, value :: c
+ !$omp declare simd (foo)
+ integer, value :: b
+ foo = a + b * c
+ end function foo
+end module declare_simd_1_mod
+ use declare_simd_1_mod
+ interface
+ function bar (a, b, c)
+ !$omp declare simd (bar)
+ integer, value :: b
+ real, value :: c
+ real :: bar
+ !$omp declare simd (bar) simdlen (4) linear (b : 2)
+ !$omp declare simd (bar) simdlen (16) inbranch
+ double precision, value :: a
+ end function bar
+ end interface
+ integer :: i
+ double precision :: a(128)
+ real :: b(128), d(128)
+ data d /171., 414., 745., 1164., 1671., 2266., 2949., 3720., 4579., &
+ & 5526., 6561., 7684., 8895., 10194., 11581., 13056., 14619., &
+ & 16270., 18009., 19836., 21751., 23754., 25845., 28024., &
+ & 30291., 32646., 35089., 37620., 40239., 42946., 45741., &
+ & 48624., 51595., 54654., 57801., 61036., 64359., 67770., &
+ & 71269., 74856., 78531., 82294., 86145., 90084., 94111., &
+ & 98226., 102429., 106720., 111099., 115566., 120121., 124764., &
+ & 129495., 134314., 139221., 144216., 149299., 154470., 159729., &
+ & 165076., 170511., 176034., 181645., 187344., 193131., 199006., &
+ & 204969., 211020., 217159., 223386., 229701., 236104., 242595., &
+ & 249174., 255841., 262596., 269439., 276370., 283389., 290496., &
+ & 297691., 304974., 312345., 319804., 327351., 334986., 342709., &
+ & 350520., 358419., 366406., 374481., 382644., 390895., 399234., &
+ & 407661., 416176., 424779., 433470., 442249., 451116., 460071., &
+ & 469114., 478245., 487464., 496771., 506166., 515649., 525220., &
+ & 534879., 544626., 554461., 564384., 574395., 584494., 594681., &
+ & 604956., 615319., 625770., 636309., 646936., 657651., 668454., &
+ & 679345., 690324., 701391., 712546., 723789., 735120./
+ !$omp simd
+ do i = 1, 128
+ a(i) = 7.0 * i + 16.0
+ b(i) = 5.0 * i + 12.0
+ end do
+ !$omp simd
+ do i = 1, 128
+ b(i) = foo (a(i), 3, b(i))
+ end do
+ !$omp simd
+ do i = 1, 128
+ b(i) = bar (a(i), 2 * i, b(i))
+ end do
+ if (any (b.ne.d)) call abort
+ !$omp simd
+ do i = 1, 128
+ b(i) = i * 2.0
+ end do
+ !$omp simd
+ do i = 1, 128
+ b(i) = baz (7.0_8, 2, b(i))
+ end do
+ do i = 1, 128
+ if (b(i).ne.(7.0 + 4.0 * i)) call abort
+ end do
+contains
+ function baz (x, y, z)
+ !$omp declare simd (baz) simdlen (8) uniform (x, y)
+ !$omp declare simd (baz)
+ integer, value :: y
+ real, value :: z
+ real :: baz
+ double precision, value :: x
+ baz = x + y * z
+ end function baz
+end
+function bar (a, b, c)
+ integer, value :: b
+ real, value :: c
+ real :: bar
+ double precision, value :: a
+ !$omp declare simd (bar)
+ !$omp declare simd (bar) simdlen (4) linear (b : 2)
+ bar = a + b * c
+end function bar
diff --git a/libgomp/testsuite/libgomp.fortran/declare-simd-2.f90 b/libgomp/testsuite/libgomp.fortran/declare-simd-2.f90
new file mode 100644
index 00000000000..30c63f706ef
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/declare-simd-2.f90
@@ -0,0 +1,25 @@
+! { dg-do run { target vect_simd_clones } }
+! { dg-options "-fno-inline" }
+! { dg-additional-sources declare-simd-3.f90 }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+module declare_simd_2_mod
+ contains
+ real function foo (a, b, c)
+ !$omp declare simd (foo) simdlen (4) uniform (a) linear (b : 5)
+ double precision, value :: a
+ real, value :: c
+ !$omp declare simd (foo)
+ integer, value :: b
+ foo = a + b * c
+ end function foo
+end module declare_simd_2_mod
+
+ interface
+ subroutine bar ()
+ end subroutine bar
+ end interface
+
+ call bar ()
+end
diff --git a/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90 b/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90
new file mode 100644
index 00000000000..031625ec435
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90
@@ -0,0 +1,22 @@
+! Don't compile this anywhere, it is just auxiliary
+! file compiled together with declare-simd-2.f90
+! to verify inter-CU module handling of omp declare simd.
+! { dg-do compile { target { lp64 && { ! lp64 } } } }
+
+subroutine bar
+ use declare_simd_2_mod
+ real :: b(128)
+ integer :: i
+
+ !$omp simd
+ do i = 1, 128
+ b(i) = i * 2.0
+ end do
+ !$omp simd
+ do i = 1, 128
+ b(i) = foo (7.0_8, 5 * i, b(i))
+ end do
+ do i = 1, 128
+ if (b(i).ne.(7.0 + 10.0 * i * i)) call abort
+ end do
+end subroutine bar
diff --git a/libgomp/testsuite/libgomp.fortran/depend-1.f90 b/libgomp/testsuite/libgomp.fortran/depend-1.f90
new file mode 100644
index 00000000000..030d3fb6a55
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/depend-1.f90
@@ -0,0 +1,203 @@
+! { dg-do run }
+
+ call dep ()
+ call dep2 ()
+ call dep3 ()
+ call firstpriv ()
+ call antidep ()
+ call antidep2 ()
+ call antidep3 ()
+ call outdep ()
+ call concurrent ()
+ call concurrent2 ()
+ call concurrent3 ()
+contains
+ subroutine dep
+ integer :: x
+ x = 1
+ !$omp parallel
+ !$omp single
+ !$omp task shared (x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+ end subroutine dep
+
+ subroutine dep2
+ integer :: x
+ !$omp parallel
+ !$omp single private (x)
+ x = 1
+ !$omp task shared (x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp taskwait
+ !$omp end single
+ !$omp end parallel
+ end subroutine dep2
+
+ subroutine dep3
+ integer :: x
+ !$omp parallel private (x)
+ x = 1
+ !$omp single
+ !$omp task shared (x) depend(out: x)
+ x = 2
+ !$omp endtask
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp endtask
+ !$omp endsingle
+ !$omp endparallel
+ end subroutine dep3
+
+ subroutine firstpriv
+ integer :: x
+ !$omp parallel private (x)
+ !$omp single
+ x = 1
+ !$omp task depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp task depend(in: x)
+ if (x.ne.1) call abort
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+ end subroutine firstpriv
+
+ subroutine antidep
+ integer :: x
+ x = 1
+ !$omp parallel
+ !$omp single
+ !$omp task shared(x) depend(in: x)
+ if (x.ne.1) call abort
+ !$omp end task
+ !$omp task shared(x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+ end subroutine antidep
+
+ subroutine antidep2
+ integer :: x
+ !$omp parallel private (x)
+ !$omp single
+ x = 1
+ !$omp taskgroup
+ !$omp task shared(x) depend(in: x)
+ if (x.ne.1) call abort
+ !$omp end task
+ !$omp task shared(x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end single
+ !$omp end parallel
+ end subroutine antidep2
+
+ subroutine antidep3
+ integer :: x
+ !$omp parallel
+ x = 1
+ !$omp single
+ !$omp task shared(x) depend(in: x)
+ if (x.ne.1) call abort
+ !$omp end task
+ !$omp task shared(x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+ end subroutine antidep3
+
+ subroutine outdep
+ integer :: x
+ !$omp parallel private (x)
+ !$omp single
+ x = 0
+ !$omp task shared(x) depend(out: x)
+ x = 1
+ !$omp end task
+ !$omp task shared(x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp taskwait
+ if (x.ne.2) call abort
+ !$omp end single
+ !$omp end parallel
+ end subroutine outdep
+
+ subroutine concurrent
+ integer :: x
+ x = 1
+ !$omp parallel
+ !$omp single
+ !$omp task shared (x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+ end subroutine concurrent
+
+ subroutine concurrent2
+ integer :: x
+ !$omp parallel private (x)
+ !$omp single
+ x = 1
+ !$omp task shared (x) depend(out: x)
+ x = 2;
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp taskwait
+ !$omp end single
+ !$omp end parallel
+ end subroutine concurrent2
+
+ subroutine concurrent3
+ integer :: x
+ !$omp parallel private (x)
+ x = 1
+ !$omp single
+ !$omp task shared (x) depend(out: x)
+ x = 2
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp task shared (x) depend(in: x)
+ if (x.ne.2) call abort
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+ end subroutine concurrent3
+end
diff --git a/libgomp/testsuite/libgomp.fortran/depend-2.f90 b/libgomp/testsuite/libgomp.fortran/depend-2.f90
new file mode 100644
index 00000000000..0694ce74206
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/depend-2.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+
+ integer :: x(3:6, 7:12), y
+ y = 1
+ !$omp parallel shared (x, y)
+ !$omp single
+ !$omp taskgroup
+ !$omp task depend(in: x(:, :))
+ if (y.ne.1) call abort
+ !$omp end task
+ !$omp task depend(out: x(:, :))
+ y = 2
+ !$omp end task
+ !$omp end taskgroup
+ !$omp taskgroup
+ !$omp task depend(in: x(4, 7))
+ if (y.ne.2) call abort
+ !$omp end task
+ !$omp task depend(out: x(4:4, 7:7))
+ y = 3
+ !$omp end task
+ !$omp end taskgroup
+ !$omp taskgroup
+ !$omp task depend(in: x(4:, 8:))
+ if (y.ne.3) call abort
+ !$omp end task
+ !$omp task depend(out: x(4:6, 8:12))
+ y = 4
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end single
+ !$omp end parallel
+ if (y.ne.4) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/depend-3.f90 b/libgomp/testsuite/libgomp.fortran/depend-3.f90
new file mode 100644
index 00000000000..11be6410692
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/depend-3.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+
+ integer :: x(2, 3)
+ integer, allocatable :: z(:, :)
+ allocate (z(-2:3, 2:4))
+ call foo (x, z)
+contains
+ subroutine foo (x, z)
+ integer :: x(:, :), y
+ integer, allocatable :: z(:, :)
+ y = 1
+ !$omp parallel shared (x, y, z)
+ !$omp single
+ !$omp taskgroup
+ !$omp task depend(in: x)
+ if (y.ne.1) call abort
+ !$omp end task
+ !$omp task depend(out: x(1:2, 1:3))
+ y = 2
+ !$omp end task
+ !$omp end taskgroup
+ !$omp taskgroup
+ !$omp task depend(in: z)
+ if (y.ne.2) call abort
+ !$omp end task
+ !$omp task depend(out: z(-2:3, 2:4))
+ y = 3
+ !$omp end task
+ !$omp end taskgroup
+ !$omp taskgroup
+ !$omp task depend(in: x)
+ if (y.ne.3) call abort
+ !$omp end task
+ !$omp task depend(out: x(1:, 1:))
+ y = 4
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end single
+ !$omp end parallel
+ if (y.ne.4) call abort
+ end subroutine
+end
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn5.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
new file mode 100644
index 00000000000..f67bd47e17d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
@@ -0,0 +1,96 @@
+! { dg-do run }
+
+ interface
+ subroutine bar (q)
+ integer :: q(19:)
+ end subroutine
+ end interface
+ integer :: q(7:15)
+ q(:) = 5
+ call bar (q)
+end
+subroutine bar (q)
+ use iso_c_binding, only: c_ptr, c_loc, c_int
+ integer :: a, b, c, d(2:3,4:5), q(19:), h, k, m, n, o, p
+ integer(c_int), target :: e(64)
+ type (c_ptr) :: f, g(64)
+ logical :: l
+ a = 1
+ b = 2
+ c = 3
+ d = 4
+ l = .false.
+ f = c_loc (e)
+ call foo
+contains
+ subroutine foo
+ use iso_c_binding, only: c_sizeof
+!$omp simd linear(a:2) linear(b:1)
+ do a = 1, 20, 2
+ b = b + 1
+ end do
+!$omp end simd
+ if (a /= 21 .or. b /= 12) call abort
+!$omp simd aligned(f : c_sizeof (e(1)))
+ do b = 1, 64
+ g(b) = f
+ end do
+!$omp end simd
+!$omp parallel
+!$omp single
+!$omp taskgroup
+!$omp task depend(out : a, d(2:2,4:5))
+ a = a + 1
+ d(2:2,4:5) = d(2:2,4:5) + 1
+!$omp end task
+!$omp task depend(in : a, d(2:2,4:5))
+ if (a /= 22) call abort
+ if (any (d(2:2,4:5) /= 5)) call abort
+!$omp end task
+!$omp end taskgroup
+!$omp end single
+!$omp end parallel
+ b = 10
+!$omp target data map (tofrom: a, d(2:3,4:4), q) map (from: l)
+!$omp target map (tofrom: b, d(2:3,4:4))
+ l = .false.
+ if (a /= 22 .or. any (q /= 5)) l = .true.
+ if (lbound (q, 1) /= 19 .or. ubound (q, 1) /= 27) l = .true.
+ if (d(2,4) /= 5 .or. d(3,4) /= 4) l = .true.
+ l = l .or. (b /= 10)
+ a = 6
+ b = 11
+ q = 8
+ d(2:3,4:4) = 9
+!$omp end target
+!$omp target update from (a, q, d(2:3,4:4), l)
+ if (a /= 6 .or. l .or. b /= 11 .or. any (q /= 8)) call abort
+ if (any (d(2:3,4:4) /= 9) .or. d(2,5) /= 5 .or. d(3,5) /= 4) call abort
+ a = 12
+ b = 13
+ q = 14
+ d = 15
+!$omp target update to (a, q, d(2:3,4:4))
+!$omp target map (tofrom: b, d(2:3,4:4))
+ if (a /= 12 .or. b /= 13 .or. any (q /= 14)) l = .true.
+ l = l .or. any (d(2:3,4:4) /= 15)
+!$omp end target
+ a = 0
+ b = 1
+ c = 100
+ h = 8
+ m = 0
+ n = 64
+ o = 16
+ if (l) call abort
+!$omp target teams distribute parallel do simd if (.not.l) device(a) &
+!$omp & num_teams(b) dist_schedule(static, c) num_threads (h) &
+!$omp & reduction (+: m) safelen (n) schedule(static, o)
+ do p = 1, 64
+ m = m + 1
+ end do
+!$omp end target teams distribute parallel do simd
+ if (m /= 64) call abort
+!$omp end target data
+ end subroutine foo
+end subroutine bar
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90
new file mode 100644
index 00000000000..8e0641592fd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90
@@ -0,0 +1,59 @@
+! { dg-do run }
+ integer (kind = 4) :: a, a2
+ integer (kind = 2) :: b, b2
+ real :: c
+ double precision :: d, d2, c2
+ integer, dimension (10) :: e
+ e(:) = 5
+ e(7) = 9
+!$omp atomic write seq_cst
+ a = 1
+!$omp atomic seq_cst, write
+ b = 2
+!$omp atomic write, seq_cst
+ c = 3
+!$omp atomic seq_cst write
+ d = 4
+!$omp atomic capture seq_cst
+ a2 = a
+ a = a + 4
+!$omp end atomic
+!$omp atomic capture, seq_cst
+ b = b - 18
+ b2 = b
+!$omp end atomic
+!$omp atomic seq_cst, capture
+ c2 = c
+ c = 2.0 * c
+!$omp end atomic
+!$omp atomic seq_cst capture
+ d = d / 2.0
+ d2 = d
+!$omp end atomic
+ if (a2 .ne. 1 .or. b2 .ne. -16 .or. c2 .ne. 3 .or. d2 .ne. 2) call abort
+!$omp atomic read seq_cst
+ a2 = a
+!$omp atomic seq_cst, read
+ c2 = c
+ if (a2 .ne. 5 .or. b2 .ne. -16 .or. c2 .ne. 6 .or. d2 .ne. 2) call abort
+ a2 = 10
+ if (a2 .ne. 10) call abort
+!$omp atomic capture
+ a2 = a
+ a = e(1) + e(6) + e(7) * 2
+!$omp endatomic
+ if (a2 .ne. 5) call abort
+!$omp atomic read
+ a2 = a
+!$omp end atomic
+ if (a2 .ne. 28) call abort
+!$omp atomic capture seq_cst
+ b2 = b
+ b = e(1) + e(7) + e(5) * 2
+!$omp end atomic
+ if (b2 .ne. -16) call abort
+!$omp atomic seq_cst, read
+ b2 = b
+!$omp end atomic
+ if (b2 .ne. 24) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/openmp_version-1.f b/libgomp/testsuite/libgomp.fortran/openmp_version-1.f
index aaa888189b1..be24adcca0c 100644
--- a/libgomp/testsuite/libgomp.fortran/openmp_version-1.f
+++ b/libgomp/testsuite/libgomp.fortran/openmp_version-1.f
@@ -4,6 +4,6 @@
implicit none
include "omp_lib.h"
- if (openmp_version .ne. 201107) call abort;
+ if (openmp_version .ne. 201307) call abort;
end program main
diff --git a/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90 b/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90
index b2d1d261f27..62712c7d206 100644
--- a/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90
@@ -4,6 +4,6 @@ program main
use omp_lib
implicit none
- if (openmp_version .ne. 201107) call abort;
+ if (openmp_version .ne. 201307) call abort;
end program main
diff --git a/libgomp/testsuite/libgomp.fortran/procptr1.f90 b/libgomp/testsuite/libgomp.fortran/procptr1.f90
new file mode 100644
index 00000000000..4187739826f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/procptr1.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+ interface
+ integer function foo ()
+ end function
+ integer function bar ()
+ end function
+ integer function baz ()
+ end function
+ end interface
+ procedure(foo), pointer :: ptr
+ integer :: i
+ ptr => foo
+!$omp parallel shared (ptr)
+ if (ptr () /= 1) call abort
+!$omp end parallel
+ ptr => bar
+!$omp parallel firstprivate (ptr)
+ if (ptr () /= 2) call abort
+!$omp end parallel
+!$omp parallel sections lastprivate (ptr)
+!$omp section
+ ptr => foo
+ if (ptr () /= 1) call abort
+!$omp section
+ ptr => bar
+ if (ptr () /= 2) call abort
+!$omp section
+ ptr => baz
+ if (ptr () /= 3) call abort
+!$omp end parallel sections
+ if (ptr () /= 3) call abort
+ if (.not.associated (ptr, baz)) call abort
+end
+integer function foo ()
+ foo = 1
+end function
+integer function bar ()
+ bar = 2
+end function
+integer function baz ()
+ baz = 3
+end function
diff --git a/libgomp/testsuite/libgomp.fortran/simd1.f90 b/libgomp/testsuite/libgomp.fortran/simd1.f90
new file mode 100644
index 00000000000..b97d27f8dc5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd1.f90
@@ -0,0 +1,35 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+ type dt
+ integer :: x = 0
+ end type
+ type (dt) :: t
+ integer :: i, j, k, l, r, s, a(30)
+ integer, target :: q(30)
+ integer, pointer :: p(:)
+ !$omp declare reduction (foo : integer : &
+ !$omp & omp_out = omp_out + omp_in) initializer (omp_priv = 0)
+ !$omp declare reduction (+ : dt : omp_out%x = omp_out%x &
+ !$omp & + omp_in%x)
+ a(:) = 1
+ q(:) = 1
+ p => q
+ r = 0
+ j = 10
+ k = 20
+ s = 0
+ !$omp simd safelen (8) reduction(+:r, t) linear(j, k : 2) &
+ !$omp& private (l) aligned(p : 4) reduction(foo:s)
+ do i = 1, 30
+ l = j + k + a(i) + p(i)
+ r = r + l
+ j = j + 2
+ k = k + 2
+ s = s + l
+ t%x = t%x + l
+ end do
+ if (r.ne.2700.or.j.ne.70.or.k.ne.80.or.s.ne.2700) call abort
+ if (t%x.ne.2700) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/simd2.f90 b/libgomp/testsuite/libgomp.fortran/simd2.f90
new file mode 100644
index 00000000000..9b90bcdd019
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd2.f90
@@ -0,0 +1,101 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+ integer :: a(1024), b(1024), k, m, i, s, t
+ k = 4
+ m = 2
+ t = 1
+ do i = 1, 1024
+ a(i) = i - 513
+ b(i) = modulo (i - 52, 39)
+ if (i.lt.52.and.b(i).ne.0) b(i) = b(i) - 39
+ end do
+ s = foo (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ a(i) = i - 513
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+ k = 4
+ m = 2
+ t = 1
+ s = bar (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ a(i) = i - 513
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+ k = 4
+ m = 2
+ t = 1
+ s = baz (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+contains
+ function foo (p)
+ integer :: p(1024), u, v, i, s, foo
+ s = 0
+ !$omp simd linear(k : m + 1) reduction(+: s) lastprivate(u, v)
+ do i = 1, 1024
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp end simd
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ foo = s
+ end function foo
+ function bar (p)
+ integer :: p(1024), u, v, i, s, bar
+ s = 0
+ !$omp simd linear(k : m + 1) reduction(+: s) lastprivate(u, v)
+ do i = 1, 1024, t
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp end simd
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ bar = s
+ end function bar
+ function baz (p)
+ integer :: p(1024), u, v, i, s, baz
+ s = 0
+ !$omp simd linear(k : m + 1) reduction(+: s) lastprivate(u, v) &
+ !$omp & linear(i : t)
+ do i = 1, 1024, t
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ baz = s
+ end function baz
+end
diff --git a/libgomp/testsuite/libgomp.fortran/simd3.f90 b/libgomp/testsuite/libgomp.fortran/simd3.f90
new file mode 100644
index 00000000000..df9f4cac3fe
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd3.f90
@@ -0,0 +1,109 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+ integer :: a(1024), b(1024), k, m, i, s, t
+ k = 4
+ m = 2
+ t = 1
+ do i = 1, 1024
+ a(i) = i - 513
+ b(i) = modulo (i - 52, 39)
+ if (i.lt.52.and.b(i).ne.0) b(i) = b(i) - 39
+ end do
+ s = foo (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ a(i) = i - 513
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+ k = 4
+ m = 2
+ t = 1
+ s = bar (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ a(i) = i - 513
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+ k = 4
+ m = 2
+ t = 1
+ s = baz (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+contains
+ function foo (p)
+ integer :: p(1024), u, v, i, s, foo
+ s = 0
+ !$omp parallel
+ !$omp do simd linear(k : m + 1) reduction(+: s) lastprivate(u, v) &
+ !$omp & schedule (static, 32)
+ do i = 1, 1024
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp end do simd
+ !$omp end parallel
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ foo = s
+ end function foo
+ function bar (p)
+ integer :: p(1024), u, v, i, s, bar
+ s = 0
+ !$omp parallel
+ !$omp do simd linear(k : m + 1) reduction(+: s) lastprivate(u, v) &
+ !$omp & schedule (dynamic, 32)
+ do i = 1, 1024, t
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp end do simd
+ !$omp endparallel
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ bar = s
+ end function bar
+ function baz (p)
+ integer :: p(1024), u, v, i, s, baz
+ s = 0
+ !$omp parallel
+ !$omp do simd linear(k : m + 1) reduction(+: s) lastprivate(u, v) &
+ !$omp & linear(i : t) schedule (static, 8)
+ do i = 1, 1024, t
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp end parallel
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ baz = s
+ end function baz
+end
diff --git a/libgomp/testsuite/libgomp.fortran/simd4.f90 b/libgomp/testsuite/libgomp.fortran/simd4.f90
new file mode 100644
index 00000000000..a5b8ba0babd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd4.f90
@@ -0,0 +1,103 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+ integer :: a(1024), b(1024), k, m, i, s, t
+ k = 4
+ m = 2
+ t = 1
+ do i = 1, 1024
+ a(i) = i - 513
+ b(i) = modulo (i - 52, 39)
+ if (i.lt.52.and.b(i).ne.0) b(i) = b(i) - 39
+ end do
+ s = foo (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ a(i) = i - 513
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+ k = 4
+ m = 2
+ t = 1
+ s = bar (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ a(i) = i - 513
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+ k = 4
+ m = 2
+ t = 1
+ s = baz (b)
+ do i = 1, 1024
+ if (a(i).ne.((i - 513) * b(i))) call abort
+ if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) call abort
+ else
+ if (b(i).ne.(modulo (i - 52, 39))) call abort
+ end if
+ end do
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) call abort
+contains
+ function foo (p)
+ integer :: p(1024), u, v, i, s, foo
+ s = 0
+ !$omp parallel do simd linear(k : m + 1) reduction(+: s) &
+ !$omp & lastprivate(u, v) schedule (static, 32)
+ do i = 1, 1024
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp end parallel do simd
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ foo = s
+ end function foo
+ function bar (p)
+ integer :: p(1024), u, v, i, s, bar
+ s = 0
+ !$omp parallel do simd linear(k : m + 1) reduction(+: s) &
+ !$omp & lastprivate(u, v) schedule (dynamic, 32)
+ do i = 1, 1024, t
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ !$omp endparalleldosimd
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ bar = s
+ end function bar
+ function baz (p)
+ integer :: p(1024), u, v, i, s, baz
+ s = 0
+ !$omp parallel do simd linear(k : m + 1) reduction(+: s) &
+ !$omp & lastprivate(u, v) linear(i : t) schedule (static, 8)
+ do i = 1, 1024, t
+ a(i) = a(i) * p(i)
+ u = p(i) + k
+ k = k + m + 1
+ v = p(i) + k
+ s = s + p(i) + k
+ end do
+ if (i.ne.1025) call abort
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) call abort
+ baz = s
+ end function baz
+end
diff --git a/libgomp/testsuite/libgomp.fortran/simd5.f90 b/libgomp/testsuite/libgomp.fortran/simd5.f90
new file mode 100644
index 00000000000..7a5efecac06
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd5.f90
@@ -0,0 +1,124 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+ integer :: i, j, b, c
+ c = 0
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ b = b + 2
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ b = b + 3
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(i) linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ b = b + 2
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(i:4) linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ b = b + 3
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd collapse(2) linear(b:2) reduction(+:c)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ b = b + 2
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd collapse(2) linear(b:2) reduction(+:c) lastprivate (i, j)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ b = b + 2
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ b = b + 2
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ b = b + 3
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(i) linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ b = b + 2
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(i:4) linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ b = b + 3
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) collapse(2) linear(b:2) reduction(+:c)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ b = b + 2
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) collapse(2) linear(b:2) &
+!$omp & reduction(+:c) lastprivate (i, j)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ b = b + 2
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/simd6.f90 b/libgomp/testsuite/libgomp.fortran/simd6.f90
new file mode 100644
index 00000000000..881a8fb8db4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd6.f90
@@ -0,0 +1,135 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+ interface
+ subroutine foo (b, i, j, x)
+ integer, intent (inout) :: b
+ integer, intent (in) :: i, j, x
+ end subroutine
+ end interface
+ integer :: i, j, b, c
+ c = 0
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ call foo (b, i, j, 2)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ call foo (b, i, j, 3)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(i) linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ call foo (b, i, j, 2)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd linear(i:4) linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ call foo (b, i, j, 3)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd collapse(2) linear(b:2) reduction(+:c)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ call foo (b, i, j, 2)
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp simd collapse(2) linear(b:2) reduction(+:c) lastprivate (i, j)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ call foo (b, i, j, 2)
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ call foo (b, i, j, 2)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ call foo (b, i, j, 3)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(i) linear(b:2) reduction(+:c)
+ do i = 0, 63
+ c = c + b - (7 + 2 * i)
+ call foo (b, i, j, 2)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) linear(i:4) linear(b:3) reduction(+:c)
+ do i = 0, 63, 4
+ c = c + b - (7 + i / 4 * 3)
+ call foo (b, i, j, 3)
+ end do
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) collapse(2) linear(b:2) reduction(+:c)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ call foo (b, i, j, 2)
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+ i = 4
+ j = 4
+ b = 7
+!$omp parallel do simd schedule (static, 4) collapse(2) linear(b:2) &
+!$omp & reduction(+:c) lastprivate (i, j)
+ do i = 0, 7
+ do j = 0, 7
+ c = c + b - (7 + 2 * j + 2 * 8 * i)
+ call foo (b, i, j, 2)
+ end do
+ end do
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) call abort
+end
+subroutine foo (b, i, j, x)
+ integer, intent (inout) :: b
+ integer, intent (in) :: i, j, x
+ b = b + (i - i) + (j - j) + x
+end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/simd7.f90 b/libgomp/testsuite/libgomp.fortran/simd7.f90
new file mode 100644
index 00000000000..b0473faa9e5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/simd7.f90
@@ -0,0 +1,172 @@
+! { dg-do run }
+! { dg-additional-options "-msse2" { target sse2_runtime } }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+subroutine foo (d, e, f, g, m, n)
+ integer :: i, j, b(2:9), c(3:n), d(:), e(2:n), f(2:,3:), n
+ integer, allocatable :: g(:), h(:), k, m
+ logical :: l
+ l = .false.
+ allocate (h(2:7))
+ i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
+!$omp simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5)linear(g:6) &
+!$omp & linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l)
+ do i = 0, 63
+ l = l .or. .not.allocated (g) .or. .not.allocated (h)
+ l = l .or. .not.allocated (k) .or. .not.allocated (m)
+ l = l .or. any (b /= 7 + i) .or. any (c /= 8 + 2 * i)
+ l = l .or. any (d /= 9 + 3 * i) .or. any (e /= 10 + 4 * i)
+ l = l .or. any (f /= 11 + 5 * i) .or. any (g /= 12 + 6 * i)
+ l = l .or. any (h /= 13 + 7 * i) .or. (k /= 14 + 8 * i)
+ l = l .or. (m /= 15 + 9 * i)
+ l = l .or. (lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)
+ l = l .or. (lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)
+ l = l .or. (lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)
+ l = l .or. (lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)
+ l = l .or. (lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)
+ l = l .or. (lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)
+ l = l .or. (lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)
+ l = l .or. (lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)
+ b = b + 1; c = c + 2; d = d + 3; e = e + 4; f = f + 5; g = g + 6
+ h = h + 7; k = k + 8; m = m + 9
+ end do
+ if (l .or. i /= 64) call abort
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) call abort
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) call abort
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) call abort
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) call abort
+ if (m /= 15 + 9 * 64) call abort
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) call abort
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) call abort
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) call abort
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) call abort
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) call abort
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) call abort
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) call abort
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) call abort
+ i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
+!$omp simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5)linear(g:6) &
+!$omp & linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l) collapse(2)
+ do i = 0, 7
+ do j = 0, 7
+ l = l .or. .not.allocated (g) .or. .not.allocated (h)
+ l = l .or. .not.allocated (k) .or. .not.allocated (m)
+ l = l .or. any (b /= 7 + (8 * i + j)) .or. any (c /= 8 + 2 * (8 * i + j))
+ l = l .or. any (d /= 9 + 3 * (8 * i + j)) .or. any (e /= 10 + 4 * (8 * i + j))
+ l = l .or. any (f /= 11 + 5 * (8 * i + j)) .or. any (g /= 12 + 6 * (8 * i + j))
+ l = l .or. any (h /= 13 + 7 * (8 * i + j)) .or. (k /= 14 + 8 * (8 * i + j))
+ l = l .or. (m /= 15 + 9 * (8 * i + j))
+ l = l .or. (lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)
+ l = l .or. (lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)
+ l = l .or. (lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)
+ l = l .or. (lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)
+ l = l .or. (lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)
+ l = l .or. (lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)
+ l = l .or. (lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)
+ l = l .or. (lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)
+ b = b + 1; c = c + 2; d = d + 3; e = e + 4; f = f + 5; g = g + 6
+ h = h + 7; k = k + 8; m = m + 9
+ end do
+ end do
+ if (l .or. i /= 8 .or. j /= 8) call abort
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) call abort
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) call abort
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) call abort
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) call abort
+ if (m /= 15 + 9 * 64) call abort
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) call abort
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) call abort
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) call abort
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) call abort
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) call abort
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) call abort
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) call abort
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) call abort
+ i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
+!$omp parallel do simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5) &
+!$omp & linear(g:6)linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l)
+ do i = 0, 63
+ l = l .or. .not.allocated (g) .or. .not.allocated (h)
+ l = l .or. .not.allocated (k) .or. .not.allocated (m)
+ l = l .or. any (b /= 7 + i) .or. any (c /= 8 + 2 * i)
+ l = l .or. any (d /= 9 + 3 * i) .or. any (e /= 10 + 4 * i)
+ l = l .or. any (f /= 11 + 5 * i) .or. any (g /= 12 + 6 * i)
+ l = l .or. any (h /= 13 + 7 * i) .or. (k /= 14 + 8 * i)
+ l = l .or. (m /= 15 + 9 * i)
+ l = l .or. (lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)
+ l = l .or. (lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)
+ l = l .or. (lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)
+ l = l .or. (lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)
+ l = l .or. (lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)
+ l = l .or. (lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)
+ l = l .or. (lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)
+ l = l .or. (lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)
+ b = b + 1; c = c + 2; d = d + 3; e = e + 4; f = f + 5; g = g + 6
+ h = h + 7; k = k + 8; m = m + 9
+ end do
+ if (l .or. i /= 64) call abort
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) call abort
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) call abort
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) call abort
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) call abort
+ if (m /= 15 + 9 * 64) call abort
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) call abort
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) call abort
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) call abort
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) call abort
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) call abort
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) call abort
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) call abort
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) call abort
+ i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
+!$omp parallel do simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5) &
+!$omp & linear(g:6)linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l) collapse(2)
+ do i = 0, 7
+ do j = 0, 7
+ l = l .or. .not.allocated (g) .or. .not.allocated (h)
+ l = l .or. .not.allocated (k) .or. .not.allocated (m)
+ l = l .or. any (b /= 7 + (8 * i + j)) .or. any (c /= 8 + 2 * (8 * i + j))
+ l = l .or. any (d /= 9 + 3 * (8 * i + j)) .or. any (e /= 10 + 4 * (8 * i + j))
+ l = l .or. any (f /= 11 + 5 * (8 * i + j)) .or. any (g /= 12 + 6 * (8 * i + j))
+ l = l .or. any (h /= 13 + 7 * (8 * i + j)) .or. (k /= 14 + 8 * (8 * i + j))
+ l = l .or. (m /= 15 + 9 * (8 * i + j))
+ l = l .or. (lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)
+ l = l .or. (lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)
+ l = l .or. (lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)
+ l = l .or. (lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)
+ l = l .or. (lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)
+ l = l .or. (lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)
+ l = l .or. (lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)
+ l = l .or. (lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)
+ b = b + 1; c = c + 2; d = d + 3; e = e + 4; f = f + 5; g = g + 6
+ h = h + 7; k = k + 8; m = m + 9
+ end do
+ end do
+ if (l .or. i /= 8 .or. j /= 8) call abort
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) call abort
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) call abort
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) call abort
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) call abort
+ if (m /= 15 + 9 * 64) call abort
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) call abort
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) call abort
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) call abort
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) call abort
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) call abort
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) call abort
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) call abort
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) call abort
+end subroutine
+
+ interface
+ subroutine foo (d, e, f, g, m, n)
+ integer :: d(:), e(2:n), f(2:,3:), n
+ integer, allocatable :: g(:), m
+ end subroutine
+ end interface
+ integer, parameter :: n = 8
+ integer :: d(2:18), e(3:n+1), f(5:6,7:9)
+ integer, allocatable :: g(:), m
+ allocate (g(7:10))
+ call foo (d, e, f, g, m, n)
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target1.f90 b/libgomp/testsuite/libgomp.fortran/target1.f90
new file mode 100644
index 00000000000..c70daace497
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target1.f90
@@ -0,0 +1,58 @@
+! { dg-do run }
+
+module target1
+contains
+ subroutine foo (p, v, w, n)
+ double precision, pointer :: p(:), v(:), w(:)
+ double precision :: q(n)
+ integer :: i, n
+ !$omp target if (n > 256) map (to: v(1:n), w(:n)) map (from: p(1:n), q)
+ !$omp parallel do simd
+ do i = 1, n
+ p(i) = v(i) * w(i)
+ q(i) = p(i)
+ end do
+ !$omp end target
+ if (any (p /= q)) call abort
+ do i = 1, n
+ if (p(i) /= i * iand (i, 63)) call abort
+ end do
+ !$omp target data if (n > 256) map (to: v(1:n), w) map (from: p, q)
+ !$omp target if (n > 256)
+ do i = 1, n
+ p(i) = 1.0
+ q(i) = 2.0
+ end do
+ !$omp end target
+ !$omp target if (n > 256)
+ do i = 1, n
+ p(i) = p(i) + v(i) * w(i)
+ q(i) = q(i) + v(i) * w(i)
+ end do
+ !$omp end target
+ !$omp target if (n > 256)
+ !$omp teams distribute parallel do simd linear(i:1)
+ do i = 1, n
+ p(i) = p(i) + 2.0
+ q(i) = q(i) + 3.0
+ end do
+ !$omp end target
+ !$omp end target data
+ if (any (p + 2.0 /= q)) call abort
+ end subroutine
+end module target1
+ use target1, only : foo
+ integer :: n, i
+ double precision, pointer :: p(:), v(:), w(:)
+ n = 10000
+ allocate (p(n), v(n), w(n))
+ do i = 1, n
+ v(i) = i
+ w(i) = iand (i, 63)
+ end do
+ call foo (p, v, w, n)
+ do i = 1, n
+ if (p(i) /= i * iand (i, 63) + 3) call abort
+ end do
+ deallocate (p, v, w)
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target2.f90 b/libgomp/testsuite/libgomp.fortran/target2.f90
new file mode 100644
index 00000000000..42f704f2bb3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target2.f90
@@ -0,0 +1,96 @@
+! { dg-do run }
+! { dg-options "-fopenmp -ffree-line-length-160" }
+
+module target2
+contains
+ subroutine foo (a, b, c, d, e, f, g, n, q)
+ integer :: n, q
+ integer :: a, b(3:n), c(5:), d(2:*), e(:,:)
+ integer, pointer :: f, g(:)
+ integer :: h, i(3:n)
+ integer, pointer :: j, k(:)
+ logical :: r
+ allocate (j, k(4:n))
+ h = 14
+ i = 15
+ j = 16
+ k = 17
+ !$omp target map (to: a, b, c, d(2:n+1), e, f, g, h, i, j, k, n) map (from: r)
+ r = a /= 7
+ r = r .or. (any (b /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
+ r = r .or. (any (c /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
+ r = r .or. (any (d(2:n+1) /= 10)) .or. (lbound (d, 1) /= 2)
+ r = r .or. (any (e /= 11)) .or. (lbound (e, 1) /= 1) .or. (ubound (e, 1) /= 2)
+ r = r .or. (lbound (e, 2) /= 1) .or. (ubound (e, 2) /= 2)
+ r = r .or. (f /= 12)
+ r = r .or. (any (g /= 13)) .or. (lbound (g, 1) /= 3) .or. (ubound (g, 1) /= n)
+ r = r .or. (h /= 14)
+ r = r .or. (any (i /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
+ r = r .or. (j /= 16)
+ r = r .or. (any (k /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
+ !$omp end target
+ if (r) call abort
+ !$omp target map (to: b(3:n), c(5:n+4), d(2:n+1), e(1:,:2), g(3:n), i(3:n), k(4:n), n) map (from: r)
+ r = (any (b /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
+ r = r .or. (any (c /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
+ r = r .or. (any (d(2:n+1) /= 10)) .or. (lbound (d, 1) /= 2)
+ r = r .or. (any (e /= 11)) .or. (lbound (e, 1) /= 1) .or. (ubound (e, 1) /= 2)
+ r = r .or. (lbound (e, 2) /= 1) .or. (ubound (e, 2) /= 2)
+ r = r .or. (any (g /= 13)) .or. (lbound (g, 1) /= 3) .or. (ubound (g, 1) /= n)
+ r = r .or. (any (i /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
+ r = r .or. (any (k /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
+ !$omp end target
+ if (r) call abort
+ !$omp target map (to: b(5:n-2), c(7:n), d(4:n-2), e(1:,2:), g(5:n-3), i(6:n-4), k(5:n-5), n) map (from: r)
+ r = (any (b(5:n-2) /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
+ r = r .or. (any (c(7:n) /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
+ r = r .or. (any (d(4:n-2) /= 10)) .or. (lbound (d, 1) /= 2)
+ r = r .or. (any (e(1:,2:) /= 11)) .or. (lbound (e, 1) /= 1) .or. (ubound (e, 1) /= 2)
+ r = r .or. (lbound (e, 2) /= 1) .or. (ubound (e, 2) /= 2)
+ r = r .or. (any (g(5:n-3) /= 13)) .or. (lbound (g, 1) /= 3) .or. (ubound (g, 1) /= n)
+ r = r .or. (any (i(6:n-4) /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
+ r = r .or. (any (k(5:n-5) /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
+ !$omp end target
+ !$omp target map (to: b(q+5:n-2+q), c(q+7:q+n), d(q+4:q+n-2), e(1:q+2,2:q+2), g(5+q:n-3+q), &
+ !$omp & i(6+q:n-4+q), k(5+q:n-5+q), n) map (from: r)
+ r = (any (b(5:n-2) /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
+ r = r .or. (any (c(7:n) /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
+ r = r .or. (any (d(4:n-2) /= 10)) .or. (lbound (d, 1) /= 2)
+ r = r .or. (any (e(1:,2:) /= 11)) .or. (lbound (e, 1) /= 1) .or. (ubound (e, 1) /= 2)
+ r = r .or. (lbound (e, 2) /= 1) .or. (ubound (e, 2) /= 2)
+ r = r .or. (any (g(5:n-3) /= 13)) .or. (lbound (g, 1) /= 3) .or. (ubound (g, 1) /= n)
+ r = r .or. (any (i(6:n-4) /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
+ r = r .or. (any (k(5:n-5) /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
+ !$omp end target
+ if (r) call abort
+ !$omp target map (to: d(2:n+1), n)
+ r = a /= 7
+ r = r .or. (any (b /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
+ r = r .or. (any (c /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
+ r = r .or. (any (d(2:n+1) /= 10)) .or. (lbound (d, 1) /= 2)
+ r = r .or. (any (e /= 11)) .or. (lbound (e, 1) /= 1) .or. (ubound (e, 1) /= 2)
+ r = r .or. (lbound (e, 2) /= 1) .or. (ubound (e, 2) /= 2)
+ r = r .or. (f /= 12)
+ r = r .or. (any (g /= 13)) .or. (lbound (g, 1) /= 3) .or. (ubound (g, 1) /= n)
+ r = r .or. (h /= 14)
+ r = r .or. (any (i /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
+ r = r .or. (j /= 16)
+ r = r .or. (any (k /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
+ !$omp end target
+ if (r) call abort
+ end subroutine foo
+end module target2
+ use target2, only : foo
+ integer, parameter :: n = 15, q = 0
+ integer :: a, b(2:n-1), c(n), d(n), e(3:4, 3:4)
+ integer, pointer :: f, g(:)
+ allocate (f, g(3:n))
+ a = 7
+ b = 8
+ c = 9
+ d = 10
+ e = 11
+ f = 12
+ g = 13
+ call foo (a, b, c, d, e, f, g, n, q)
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target3.f90 b/libgomp/testsuite/libgomp.fortran/target3.f90
new file mode 100644
index 00000000000..1f197acdef7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target3.f90
@@ -0,0 +1,29 @@
+! { dg-do run }
+
+module target3
+contains
+ subroutine foo (f, g)
+ integer :: n
+ integer, pointer :: f, g(:)
+ integer, pointer :: j, k(:)
+ logical :: r
+ nullify (j)
+ k => null ()
+ !$omp target map (tofrom: f, g, j, k) map (from: r)
+ r = associated (f) .or. associated (g)
+ r = r .or. associated (j) .or. associated (k)
+ !$omp end target
+ if (r) call abort
+ !$omp target
+ r = associated (f) .or. associated (g)
+ r = r .or. associated (j) .or. associated (k)
+ !$omp end target
+ if (r) call abort
+ end subroutine foo
+end module target3
+ use target3, only : foo
+ integer, pointer :: f, g(:)
+ f => null ()
+ nullify (g)
+ call foo (f, g)
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target4.f90 b/libgomp/testsuite/libgomp.fortran/target4.f90
new file mode 100644
index 00000000000..aa2f0a5ac19
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target4.f90
@@ -0,0 +1,48 @@
+! { dg-do run }
+
+module target4
+contains
+ subroutine foo (a,m,n)
+ integer :: m,n,i,j
+ double precision :: a(m, n), t
+ !$omp target data map(a) map(to: m, n)
+ do i=1,n
+ t = 0.0d0
+ !$omp target
+ !$omp parallel do reduction(+:t)
+ do j=1,m
+ t = t + a(j,i) * a(j,i)
+ end do
+ !$omp end target
+ t = 2.0d0 * t
+ !$omp target
+ !$omp parallel do
+ do j=1,m
+ a(j,i) = a(j,i) * t
+ end do
+ !$omp end target
+ end do
+ !$omp end target data
+ end subroutine foo
+end module target4
+ use target4, only : foo
+ integer :: i, j
+ double precision :: a(8, 9), res(8, 9)
+ do i = 1, 8
+ do j = 1, 9
+ a(i, j) = i + j
+ end do
+ end do
+ call foo (a, 8, 9)
+ res = reshape ((/ 1136.0d0, 1704.0d0, 2272.0d0, 2840.0d0, 3408.0d0, 3976.0d0, &
+& 4544.0d0, 5112.0d0, 2280.0d0, 3040.0d0, 3800.0d0, 4560.0d0, 5320.0d0, 6080.0d0, &
+& 6840.0d0, 7600.0d0, 3936.0d0, 4920.0d0, 5904.0d0, 6888.0d0, 7872.0d0, 8856.0d0, &
+& 9840.0d0, 10824.0d0, 6200.0d0, 7440.0d0, 8680.0d0, 9920.0d0, 11160.0d0, 12400.0d0, &
+& 13640.0d0, 14880.0d0, 9168.0d0, 10696.0d0, 12224.0d0, 13752.0d0, 15280.0d0, 16808.0d0, &
+& 18336.0d0, 19864.0d0, 12936.0d0, 14784.0d0, 16632.0d0, 18480.0d0, 20328.0d0, 22176.0d0, &
+& 24024.0d0, 25872.0d0, 17600.0d0, 19800.0d0, 22000.0d0, 24200.0d0, 26400.0d0, 28600.0d0, &
+& 30800.0d0, 33000.0d0, 23256.0d0, 25840.0d0, 28424.0d0, 31008.0d0, 33592.0d0, 36176.0d0, &
+& 38760.0d0, 41344.0d0, 30000.0d0, 33000.0d0, 36000.0d0, 39000.0d0, 42000.0d0, 45000.0d0, &
+& 48000.0d0, 51000.0d0 /), (/ 8, 9 /))
+ if (any (a /= res)) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target5.f90 b/libgomp/testsuite/libgomp.fortran/target5.f90
new file mode 100644
index 00000000000..c46faf226f6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target5.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+ integer :: r
+ r = 0
+ call foo (r)
+ if (r /= 11) call abort
+contains
+ subroutine foo (r)
+ integer :: i, r
+ !$omp parallel
+ !$omp single
+ !$omp target teams distribute parallel do reduction (+: r)
+ do i = 1, 10
+ r = r + 1
+ end do
+ r = r + 1
+ !$omp end single
+ !$omp end parallel
+ end subroutine
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target6.f90 b/libgomp/testsuite/libgomp.fortran/target6.f90
new file mode 100644
index 00000000000..13f5a52edd2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target6.f90
@@ -0,0 +1,50 @@
+! { dg-do run }
+
+module target6
+contains
+ subroutine foo (p, v, w, n)
+ double precision, pointer :: p(:), v(:), w(:)
+ double precision :: q(n)
+ integer :: i, n
+ !$omp target data if (n > 256) map (to: v(1:n), w(:n)) map (from: p(1:n), q)
+ !$omp target if (n > 256)
+ !$omp parallel do simd
+ do i = 1, n
+ p(i) = v(i) * w(i)
+ q(i) = p(i)
+ end do
+ !$omp end target
+ !$omp target update if (n > 256) from (p)
+ do i = 1, n
+ if (p(i) /= i * iand (i, 63)) call abort
+ v(i) = v(i) + 1
+ end do
+ !$omp target update if (n > 256) to (v(1:n))
+ !$omp target if (n > 256)
+ !$omp parallel do simd
+ do i = 1, n
+ p(i) = v(i) * w(i)
+ end do
+ !$omp end target
+ !$omp end target data
+ do i = 1, n
+ if (q(i) /= (v(i) - 1) * w(i)) call abort
+ if (p(i) /= q(i) + w(i)) call abort
+ end do
+ end subroutine
+end module target6
+ use target6, only : foo
+ integer :: n, i
+ double precision, pointer :: p(:), v(:), w(:)
+ n = 10000
+ allocate (p(n), v(n), w(n))
+ do i = 1, n
+ v(i) = i
+ w(i) = iand (i, 63)
+ end do
+ call foo (p, v, w, n)
+ do i = 1, n
+ if (p(i) /= (i + 1) * iand (i, 63)) call abort
+ end do
+ deallocate (p, v, w)
+end
diff --git a/libgomp/testsuite/libgomp.fortran/target7.f90 b/libgomp/testsuite/libgomp.fortran/target7.f90
new file mode 100644
index 00000000000..0c977c44ae1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target7.f90
@@ -0,0 +1,38 @@
+! { dg-do run }
+
+ interface
+ real function foo (x)
+ !$omp declare target
+ real, intent(in) :: x
+ end function foo
+ end interface
+ integer, parameter :: n = 1000
+ integer, parameter :: c = 100
+ integer :: i, j
+ real :: a(n)
+ do i = 1, n
+ a(i) = i
+ end do
+ !$omp parallel
+ !$omp single
+ do i = 1, n, c
+ !$omp task shared(a)
+ !$omp target map(a(i:i+c-1))
+ !$omp parallel do
+ do j = i, i + c - 1
+ a(j) = foo (a(j))
+ end do
+ !$omp end target
+ !$omp end task
+ end do
+ !$omp end single
+ !$omp end parallel
+ do i = 1, n
+ if (a(i) /= i + 1) call abort
+ end do
+end
+real function foo (x)
+ !$omp declare target
+ real, intent(in) :: x
+ foo = x + 1
+end function foo
diff --git a/libgomp/testsuite/libgomp.fortran/target8.f90 b/libgomp/testsuite/libgomp.fortran/target8.f90
new file mode 100644
index 00000000000..0564e90e08e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target8.f90
@@ -0,0 +1,33 @@
+! { dg-do run }
+
+ integer, parameter :: n = 1000
+ integer, parameter :: c = 100
+ integer :: i, j
+ real :: a(n)
+ do i = 1, n
+ a(i) = i
+ end do
+ !$omp parallel
+ !$omp single
+ do i = 1, n, c
+ !$omp task shared(a)
+ !$omp target map(a(i:i+c-1))
+ !$omp parallel do
+ do j = i, i + c - 1
+ a(j) = foo (a(j))
+ end do
+ !$omp end target
+ !$omp end task
+ end do
+ !$omp end single
+ !$omp end parallel
+ do i = 1, n
+ if (a(i) /= i + 1) call abort
+ end do
+contains
+ real function foo (x)
+ !$omp declare target
+ real, intent(in) :: x
+ foo = x + 1
+ end function foo
+end
diff --git a/libgomp/testsuite/libgomp.fortran/taskgroup1.f90 b/libgomp/testsuite/libgomp.fortran/taskgroup1.f90
new file mode 100644
index 00000000000..018d3e83b92
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/taskgroup1.f90
@@ -0,0 +1,80 @@
+ integer :: v(16), i
+ do i = 1, 16
+ v(i) = i
+ end do
+
+ !$omp parallel num_threads (4)
+ !$omp single
+ !$omp taskgroup
+ do i = 1, 16, 2
+ !$omp task
+ !$omp task
+ v(i) = v(i) + 1
+ !$omp end task
+ !$omp task
+ v(i + 1) = v(i + 1) + 1
+ !$omp end task
+ !$omp end task
+ end do
+ !$omp end taskgroup
+ do i = 1, 16
+ if (v(i).ne.(i + 1)) call abort
+ end do
+ !$omp taskgroup
+ do i = 1, 16, 2
+ !$omp task
+ !$omp task
+ v(i) = v(i) + 1
+ !$omp endtask
+ !$omp task
+ v(i + 1) = v(i + 1) + 1
+ !$omp endtask
+ !$omp taskwait
+ !$omp endtask
+ end do
+ !$omp endtaskgroup
+ do i = 1, 16
+ if (v(i).ne.(i + 2)) call abort
+ end do
+ !$omp taskgroup
+ do i = 1, 16, 2
+ !$omp task
+ !$omp task
+ v(i) = v(i) + 1
+ !$omp end task
+ v(i + 1) = v(i + 1) + 1
+ !$omp end task
+ end do
+ !$omp taskwait
+ do i = 1, 16, 2
+ !$omp task
+ v(i + 1) = v(i + 1) + 1
+ !$omp end task
+ end do
+ !$omp end taskgroup
+ do i = 1, 16, 2
+ if (v(i).ne.(i + 3)) call abort
+ if (v(i + 1).ne.(i + 5)) call abort
+ end do
+ !$omp taskgroup
+ do i = 1, 16, 2
+ !$omp taskgroup
+ !$omp task
+ v(i) = v(i) + 1
+ !$omp end task
+ !$omp task
+ v(i + 1) = v(i + 1) + 1
+ !$omp end task
+ !$omp end taskgroup
+ if (v(i).ne.(i + 4).or.v(i + 1).ne.(i + 6)) call abort
+ !$omp task
+ v(i) = v(i) + 1
+ !$omp end task
+ end do
+ !$omp end taskgroup
+ do i = 1, 16
+ if (v(i).ne.(i + 5)) call abort
+ end do
+ !$omp end single
+ !$omp end parallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr1.f90 b/libgomp/testsuite/libgomp.fortran/udr1.f90
new file mode 100644
index 00000000000..5b8044fbe75
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr1.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+
+module udr1
+ type dt
+ integer :: x = 7
+ integer :: y = 9
+ end type
+end module udr1
+ use udr1, only : dt
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in)
+ integer :: i, j
+!$omp declare reduction (bar : integer : &
+!$omp & omp_out = omp_out + iand (omp_in, -4)) initializer (omp_priv = 3)
+ type (dt) :: d
+!$omp declare reduction (+ : dt : omp_out%x = omp_out%x &
+!$omp & + iand (omp_in%x, -8))
+!$omp declare reduction (foo : dt : omp_out%x = iand (omp_in%x, -8) &
+!$omp & + omp_out%x) initializer (omp_priv = dt (5, 21))
+ interface operator (+)
+ function notdefined(x, y)
+ use udr1, only : dt
+ type(dt), intent (in) :: x, y
+ type(dt) :: notdefined
+ end function
+ end interface
+ j = 0
+!$omp parallel do reduction (foo : j)
+ do i = 1, 100
+ j = j + i
+ end do
+ if (j .ne. 5050) call abort
+ j = 3
+!$omp parallel do reduction (bar : j)
+ do i = 1, 100
+ j = j + 4 * i
+ end do
+ if (j .ne. (5050 * 4 + 3)) call abort
+!$omp parallel do reduction (+ : d)
+ do i = 1, 100
+ if (d%y .ne. 9) call abort
+ d%x = d%x + 8 * i
+ end do
+ if (d%x .ne. (5050 * 8 + 7) .or. d%y .ne. 9) call abort
+ d = dt (5, 21)
+!$omp parallel do reduction (foo : d)
+ do i = 1, 100
+ if (d%y .ne. 21) call abort
+ d%x = d%x + 8 * i
+ end do
+ if (d%x .ne. (5050 * 8 + 5) .or. d%y .ne. 21) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr10.f90 b/libgomp/testsuite/libgomp.fortran/udr10.f90
new file mode 100644
index 00000000000..b64b4f48800
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr10.f90
@@ -0,0 +1,32 @@
+! { dg-do run }
+
+module udr10m
+ type dt
+ integer :: x = 0
+ end type
+!$omp declare reduction(.add.:dt:omp_out=omp_out.add.omp_in)
+!$omp declare reduction(+:dt:omp_out=omp_out+omp_in)
+ interface operator(+)
+ module procedure addme
+ end interface
+ interface operator(.add.)
+ module procedure addme
+ end interface
+contains
+ type(dt) function addme (x, y)
+ type (dt), intent (in) :: x, y
+ addme%x = x%x + y%x
+ end function addme
+end module udr10m
+program udr10
+ use udr10m, only : operator(.localadd.) => operator(.add.), &
+& operator(+), dl => dt
+ type(dl) :: j, k
+ integer :: i
+!$omp parallel do reduction(+:j) reduction(.localadd.:k)
+ do i = 1, 100
+ j = j .localadd. dl(i)
+ k = k + dl(i * 2)
+ end do
+ if (j%x /= 5050 .or. k%x /= 10100) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr11.f90 b/libgomp/testsuite/libgomp.fortran/udr11.f90
new file mode 100644
index 00000000000..61fb196105d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr11.f90
@@ -0,0 +1,95 @@
+! { dg-do run }
+
+module udr11
+ type dt
+ integer :: x = 0
+ end type
+end module udr11
+ use udr11, only : dt
+!$omp declare reduction(+:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(-:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(*:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(.and.:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(.or.:dt:omp_out%x=omp_out%x+3*omp_in%x)
+!$omp declare reduction(.eqv.:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(.neqv.:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(min:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(max:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(iand:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(ior:dt:omp_out%x=omp_out%x+omp_in%x)
+!$omp declare reduction(ieor:dt:omp_out%x=omp_out%x+omp_in%x)
+ interface operator(.and.)
+ function addme1 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme1
+ end function addme1
+ end interface
+ interface operator(.or.)
+ function addme2 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme2
+ end function addme2
+ end interface
+ interface operator(.eqv.)
+ function addme3 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme3
+ end function addme3
+ end interface
+ interface operator(.neqv.)
+ function addme4 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme4
+ end function addme4
+ end interface
+ interface operator(+)
+ function addme5 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme5
+ end function addme5
+ end interface
+ interface operator(-)
+ function addme6 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme6
+ end function addme6
+ end interface
+ interface operator(*)
+ function addme7 (x, y)
+ use udr11, only : dt
+ type (dt), intent (in) :: x, y
+ type(dt) :: addme7
+ end function addme7
+ end interface
+ type(dt) :: j, k, l, m, n, o, p, q, r, s, t, u
+ integer :: i
+!$omp parallel do reduction(.and.:j) reduction(.or.:k) &
+!$omp & reduction(.eqv.:l) reduction(.neqv.:m) &
+!$omp & reduction(min:n) reduction(max:o) &
+!$omp & reduction(iand:p) reduction(ior:q) reduction (ieor:r) &
+!$omp & reduction(+:s) reduction(-:t) reduction(*:u)
+ do i = 1, 100
+ j%x = j%x + i
+ k%x = k%x + 2 * i
+ l%x = l%x + 3 * i
+ m%x = m%x + i
+ n%x = n%x + 2 * i
+ o%x = o%x + 3 * i
+ p%x = p%x + i
+ q%x = q%x + 2 * i
+ r%x = r%x + 3 * i
+ s%x = s%x + i
+ t%x = t%x + 2 * i
+ u%x = u%x + 3 * i
+ end do
+ if (j%x /= 5050 .or. k%x /= 30300 .or. l%x /= 15150) call abort
+ if (m%x /= 5050 .or. n%x /= 10100 .or. o%x /= 15150) call abort
+ if (p%x /= 5050 .or. q%x /= 10100 .or. r%x /= 15150) call abort
+ if (s%x /= 5050 .or. t%x /= 10100 .or. u%x /= 15150) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr12.f90 b/libgomp/testsuite/libgomp.fortran/udr12.f90
new file mode 100644
index 00000000000..601bca6a93e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr12.f90
@@ -0,0 +1,76 @@
+! { dg-do run }
+
+ interface
+ elemental subroutine sub1 (x, y)
+ integer, intent(in) :: y
+ integer, intent(out) :: x
+ end subroutine
+ elemental function fn2 (x)
+ integer, intent(in) :: x
+ integer :: fn2
+ end function
+ end interface
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in) initializer (omp_priv = 0)
+!$omp declare reduction (bar : integer : omp_out = fn1 (omp_out, omp_in)) &
+!$omp & initializer (sub1 (omp_priv, omp_orig))
+!$omp declare reduction (baz : integer : sub2 (omp_out, omp_in)) &
+!$omp initializer (omp_priv = fn2 (omp_orig))
+ interface
+ elemental function fn1 (x, y)
+ integer, intent(in) :: x, y
+ integer :: fn1
+ end function
+ elemental subroutine sub2 (x, y)
+ integer, intent(in) :: y
+ integer, intent(inout) :: x
+ end subroutine
+ end interface
+ integer :: a(10), b, r
+ a(:) = 0
+ b = 0
+ r = 0
+!$omp parallel reduction (foo : a, b) reduction (+: r)
+ a = a + 2
+ b = b + 3
+ r = r + 1
+!$omp end parallel
+ if (any (a /= 2 * r) .or. b /= 3 * r) call abort
+ a(:) = 0
+ b = 0
+ r = 0
+!$omp parallel reduction (bar : a, b) reduction (+: r)
+ a = a + 2
+ b = b + 3
+ r = r + 1
+!$omp end parallel
+ if (any (a /= 4 * r) .or. b /= 6 * r) call abort
+ a(:) = 0
+ b = 0
+ r = 0
+!$omp parallel reduction (baz : a, b) reduction (+: r)
+ a = a + 2
+ b = b + 3
+ r = r + 1
+!$omp end parallel
+ if (any (a /= 2 * r) .or. b /= 3 * r) call abort
+end
+elemental function fn1 (x, y)
+ integer, intent(in) :: x, y
+ integer :: fn1
+ fn1 = x + 2 * y
+end function
+elemental subroutine sub1 (x, y)
+ integer, intent(in) :: y
+ integer, intent(out) :: x
+ x = 0
+end subroutine
+elemental function fn2 (x)
+ integer, intent(in) :: x
+ integer :: fn2
+ fn2 = x
+end function
+elemental subroutine sub2 (x, y)
+ integer, intent(inout) :: x
+ integer, intent(in) :: y
+ x = x + y
+end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/udr13.f90 b/libgomp/testsuite/libgomp.fortran/udr13.f90
new file mode 100644
index 00000000000..0da1da4bc65
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr13.f90
@@ -0,0 +1,106 @@
+! { dg-do run }
+
+ interface
+ subroutine sub1 (x, y)
+ integer, intent(in) :: y(:)
+ integer, intent(out) :: x(:)
+ end subroutine
+ function fn2 (x, m1, m2, n1, n2)
+ integer, intent(in) :: x(:,:), m1, m2, n1, n2
+ integer :: fn2(m1:m2,n1:n2)
+ end function
+ subroutine sub3 (x, y)
+ integer, allocatable, intent(in) :: y(:,:)
+ integer, allocatable, intent(inout) :: x(:,:)
+ end subroutine
+ end interface
+!$omp declare reduction (foo : integer : sub3 (omp_out, omp_in)) &
+!$omp initializer (omp_priv = fn3 (omp_orig))
+!$omp declare reduction (bar : integer : omp_out = fn1 (omp_out, omp_in, &
+!$omp & lbound (omp_out, 1), ubound (omp_out, 1))) &
+!$omp & initializer (sub1 (omp_priv, omp_orig))
+!$omp declare reduction (baz : integer : sub2 (omp_out, omp_in)) &
+!$omp initializer (omp_priv = fn2 (omp_orig, lbound (omp_priv, 1), &
+!$omp ubound (omp_priv, 1), lbound (omp_priv, 2), ubound (omp_priv, 2)))
+ interface
+ function fn1 (x, y, m1, m2)
+ integer, intent(in) :: x(:), y(:), m1, m2
+ integer :: fn1(m1:m2)
+ end function
+ subroutine sub2 (x, y)
+ integer, intent(in) :: y(:,:)
+ integer, intent(inout) :: x(:,:)
+ end subroutine
+ function fn3 (x)
+ integer, allocatable, intent(in) :: x(:,:)
+ integer, allocatable :: fn3(:,:)
+ end function
+ end interface
+ integer :: a(10), b(3:5,7:9), r
+ integer, allocatable :: c(:,:)
+ a(:) = 0
+ r = 0
+!$omp parallel reduction (bar : a) reduction (+: r)
+ if (lbound (a, 1) /= 1 .or. ubound (a, 1) /= 10) call abort
+ a = a + 2
+ r = r + 1
+!$omp end parallel
+ if (any (a /= 4 * r) ) call abort
+ b(:,:) = 0
+ allocate (c (4:6,8:10))
+ c(:,:) = 0
+ r = 0
+!$omp parallel reduction (baz : b, c) reduction (+: r)
+ if (lbound (b, 1) /= 3 .or. ubound (b, 1) /= 5) call abort
+ if (lbound (b, 2) /= 7 .or. ubound (b, 2) /= 9) call abort
+ if (.not. allocated (c)) call abort
+ if (lbound (c, 1) /= 4 .or. ubound (c, 1) /= 6) call abort
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 10) call abort
+ b = b + 3
+ c = c + 4
+ r = r + 1
+!$omp end parallel
+ if (any (b /= 3 * r) .or. any (c /= 4 * r)) call abort
+ deallocate (c)
+ allocate (c (0:1,7:11))
+ c(:,:) = 0
+ r = 0
+!$omp parallel reduction (foo : c) reduction (+: r)
+ if (.not. allocated (c)) call abort
+ if (lbound (c, 1) /= 0 .or. ubound (c, 1) /= 1) call abort
+ if (lbound (c, 2) /= 7 .or. ubound (c, 2) /= 11) call abort
+ c = c + 5
+ r = r + 1
+!$omp end parallel
+ if (any (c /= 10 * r)) call abort
+end
+function fn1 (x, y, m1, m2)
+ integer, intent(in) :: x(:), y(:), m1, m2
+ integer :: fn1(m1:m2)
+ fn1 = x + 2 * y
+end function
+subroutine sub1 (x, y)
+ integer, intent(in) :: y(:)
+ integer, intent(out) :: x(:)
+ x = 0
+end subroutine
+function fn2 (x, m1, m2, n1, n2)
+ integer, intent(in) :: x(:,:), m1, m2, n1, n2
+ integer :: fn2(m1:m2,n1:n2)
+ fn2 = x
+end function
+subroutine sub2 (x, y)
+ integer, intent(inout) :: x(:,:)
+ integer, intent(in) :: y(:,:)
+ x = x + y
+end subroutine
+function fn3 (x)
+ integer, allocatable, intent(in) :: x(:,:)
+ integer, allocatable :: fn3(:,:)
+ fn3 = x
+end function
+subroutine sub3 (x, y)
+ integer, allocatable, intent(inout) :: x(:,:)
+ integer, allocatable, intent(in) :: y(:,:)
+ x = x + 2 * y
+end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/udr14.f90 b/libgomp/testsuite/libgomp.fortran/udr14.f90
new file mode 100644
index 00000000000..d6974585578
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr14.f90
@@ -0,0 +1,50 @@
+! { dg-do run }
+
+ type dt
+ integer :: g
+ integer, allocatable :: h(:)
+ end type
+!$omp declare reduction (baz : dt : bar (omp_out, omp_in)) &
+!$omp & initializer (foo (omp_priv, omp_orig))
+ integer :: r
+ type (dt), allocatable :: a(:)
+ allocate (a(7:8))
+ a(:)%g = 0
+ a(7)%h = (/ 0, 0, 0 /)
+ r = 0
+!$omp parallel reduction(+:r) reduction (baz:a)
+ if (.not.allocated (a)) call abort
+ if (lbound (a, 1) /= 7 .or. ubound (a, 1) /= 8) call abort
+ if (.not.allocated (a(7)%h)) call abort
+ if (allocated (a(8)%h)) call abort
+ if (lbound (a(7)%h, 1) /= 1 .or. ubound (a(7)%h, 1) /= 3) call abort
+ a(:)%g = a(:)%g + 2
+ a(7)%h = a(7)%h + 3
+ r = r + 1
+!$omp end parallel
+ if (.not.allocated (a)) call abort
+ if (lbound (a, 1) /= 7 .or. ubound (a, 1) /= 8) call abort
+ if (.not.allocated (a(7)%h)) call abort
+ if (allocated (a(8)%h)) call abort
+ if (lbound (a(7)%h, 1) /= 1 .or. ubound (a(7)%h, 1) /= 3) call abort
+ if (any (a(:)%g /= 2 * r) .or. any (a(7)%h(:) /= 3 * r)) call abort
+contains
+ subroutine foo (x, y)
+ type (dt), allocatable :: x(:), y(:)
+ if (allocated (x) .neqv. allocated (y)) call abort
+ if (lbound (x, 1) /= lbound (y, 1)) call abort
+ if (ubound (x, 1) /= ubound (y, 1)) call abort
+ if (allocated (x(7)%h) .neqv. allocated (y(7)%h)) call abort
+ if (allocated (x(8)%h) .neqv. allocated (y(8)%h)) call abort
+ if (lbound (x(7)%h, 1) /= lbound (y(7)%h, 1)) call abort
+ if (ubound (x(7)%h, 1) /= ubound (y(7)%h, 1)) call abort
+ x(7)%g = 0
+ x(7)%h = 0
+ x(8)%g = 0
+ end subroutine
+ subroutine bar (x, y)
+ type (dt), allocatable :: x(:), y(:)
+ x(:)%g = x(:)%g + y(:)%g
+ x(7)%h(:) = x(7)%h(:) + y(7)%h(:)
+ end subroutine
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr15.f90 b/libgomp/testsuite/libgomp.fortran/udr15.f90
new file mode 100644
index 00000000000..2d1169568dd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr15.f90
@@ -0,0 +1,64 @@
+! { dg-do run }
+
+module udr15m1
+ integer, parameter :: a = 6
+ integer :: b
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in)
+!$omp declare reduction (.add. : integer : &
+!$omp & omp_out = omp_out .add. f3 (omp_in, -4)) &
+!$omp & initializer (s1 (omp_priv, omp_orig))
+ interface operator (.add.)
+ module procedure f1
+ end interface
+contains
+ integer function f1 (x, y)
+ integer, intent (in) :: x, y
+ f1 = x + y
+ end function f1
+ integer function f3 (x, y)
+ integer, intent (in) :: x, y
+ f3 = iand (x, y)
+ end function f3
+ subroutine s1 (x, y)
+ integer, intent (in) :: y
+ integer, intent (out) :: x
+ x = 3
+ end subroutine s1
+end module udr15m1
+module udr15m2
+ use udr15m1, f4 => f1, f5 => f3, s2 => s1, operator (.addtwo.) => operator (.add.)
+ type dt
+ integer :: x
+ end type
+!$omp declare reduction (+ : dt : omp_out = f6 (omp_out + omp_in)) &
+!$omp & initializer (s3 (omp_priv))
+ interface operator (+)
+ module procedure f2
+ end interface
+contains
+ type(dt) function f2 (x, y)
+ type(dt), intent (in) :: x, y
+ f2%x = x%x + y%x
+ end function f2
+ type(dt) function f6 (x)
+ type(dt), intent (in) :: x
+ f6%x = x%x
+ end function f6
+ subroutine s3 (x)
+ type(dt), intent (out) :: x
+ x = dt(0)
+ end subroutine
+end module udr15m2
+ use udr15m2, operator (.addthree.) => operator (.addtwo.), &
+ f7 => f4, f8 => f6, s4 => s3
+ integer :: i, j
+ type(dt) :: d
+ j = 3
+ d%x = 0
+!$omp parallel do reduction (.addthree.: j) reduction (+ : d)
+ do i = 1, 100
+ j = j.addthree.iand (i, -4)
+ d = d + dt(i)
+ end do
+ if (d%x /= 5050 .or. j /= 4903) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr2.f90 b/libgomp/testsuite/libgomp.fortran/udr2.f90
new file mode 100644
index 00000000000..861a4b27022
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr2.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+
+module udr2
+ type dt
+ integer :: x = 7
+ integer :: y = 9
+ end type
+end module udr2
+ use udr2, only : dt
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in)
+ integer :: i, j(2:4,3:5)
+!$omp declare reduction (bar : integer : &
+!$omp & omp_out = omp_out + iand (omp_in, -4)) initializer (omp_priv = 3)
+ interface operator (+)
+ function notdefined(x, y)
+ use udr2, only : dt
+ type(dt), intent (in) :: x, y
+ type(dt) :: notdefined
+ end function
+ end interface
+ type (dt) :: d(2:4,3:5)
+!$omp declare reduction (+ : dt : omp_out%x = omp_out%x &
+!$omp & + iand (omp_in%x, -8))
+!$omp declare reduction (foo : dt : omp_out%x = iand (omp_in%x, -8) &
+!$omp & + omp_out%x) initializer (omp_priv = dt (5, 21))
+ j = 0
+!$omp parallel do reduction (foo : j)
+ do i = 1, 100
+ j = j + i
+ end do
+ if (any(j .ne. 5050)) call abort
+ j = 3
+!$omp parallel do reduction (bar : j)
+ do i = 1, 100
+ j = j + 4 * i
+ end do
+ if (any(j .ne. (5050 * 4 + 3))) call abort
+!$omp parallel do reduction (+ : d)
+ do i = 1, 100
+ if (any(d%y .ne. 9)) call abort
+ d%x = d%x + 8 * i
+ end do
+ if (any(d%x .ne. (5050 * 8 + 7)) .or. any(d%y .ne. 9)) call abort
+ d = dt (5, 21)
+!$omp parallel do reduction (foo : d)
+ do i = 1, 100
+ if (any(d%y .ne. 21)) call abort
+ d%x = d%x + 8 * i
+ end do
+ if (any(d%x .ne. (5050 * 8 + 5)) .or. any(d%y .ne. 21)) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr3.f90 b/libgomp/testsuite/libgomp.fortran/udr3.f90
new file mode 100644
index 00000000000..258b6722000
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr3.f90
@@ -0,0 +1,38 @@
+! { dg-do run }
+
+!$omp declare reduction (foo : character(kind=1, len=*) &
+!$omp & : omp_out = trim(omp_out) // omp_in) initializer (omp_priv = '')
+!$omp declare reduction (bar : character(kind=1, len=:) &
+!$omp & : omp_out = trim(omp_in) // omp_out) initializer (omp_priv = '')
+!$omp declare reduction (baz : character(kind=1, len=1) &
+!$omp & : omp_out = char (ichar (omp_out) + ichar (omp_in) &
+!$omp & - ichar ('0'))) initializer (omp_priv = '0')
+!$omp declare reduction (baz : character(kind=1, len=2) &
+!$omp & : omp_out = char (ichar (omp_out(1:1)) + ichar (omp_in(1:1)) &
+!$omp & - ichar ('0')) // char (ichar (omp_out(2:2)) + &
+!$omp & ichar (omp_in(2:2)) - ichar ('0'))) initializer (omp_priv = '00')
+ character(kind=1, len=64) :: c, d
+ character(kind = 1, len=1) :: e
+ character(kind = 1, len=1+1) :: f
+ integer :: i
+ c = ''
+ d = ''
+ e = '0'
+ f = '00'
+!$omp parallel do reduction (foo : c) reduction (bar : d) &
+!$omp & reduction (baz : e, f)
+ do i = 1, 64
+ c = trim(c) // char (ichar ('0') + i)
+ d = char (ichar ('0') + i) // d
+ e = char (ichar (e) + mod (i, 3))
+ f = char (ichar (f(1:1)) + mod (i, 2)) &
+& // char (ichar (f(2:2)) + mod (i, 3))
+ end do
+ do i = 1, 64
+ if (index (c, char (ichar ('0') + i)) .eq. 0) call abort
+ if (index (d, char (ichar ('0') + i)) .eq. 0) call abort
+ end do
+ if (e.ne.char (ichar ('0') + 64)) call abort
+ if (f(1:1).ne.char (ichar ('0') + 32)) call abort
+ if (f(2:2).ne.char (ichar ('0') + 64)) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr4.f90 b/libgomp/testsuite/libgomp.fortran/udr4.f90
new file mode 100644
index 00000000000..89365476af7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr4.f90
@@ -0,0 +1,50 @@
+! { dg-do run }
+
+!$omp declare reduction (foo : character(kind=1, len=*) &
+!$omp & : omp_out = fn (omp_out, omp_in)) initializer (omp_priv = '')
+!$omp declare reduction (bar : character(kind=1, len=:) &
+!$omp & : omp_out = fn (omp_in, omp_out)) initializer (omp_priv = '')
+!$omp declare reduction (baz : character(kind=1, len=1) &
+!$omp & : omp_out = char (ichar (omp_out) + ichar (omp_in) &
+!$omp & - ichar ('0'))) initializer (omp_priv = '0')
+!$omp declare reduction (baz : character(kind=1, len=2) &
+!$omp & : omp_out = char (ichar (omp_out(1:1)) + ichar (omp_in(1:1)) &
+!$omp & - ichar ('0')) // char (ichar (omp_out(2:2)) + &
+!$omp & ichar (omp_in(2:2)) - ichar ('0'))) initializer (omp_priv = '00')
+ interface
+ elemental function fn (x, y)
+ character (len=64), intent (in) :: x, y
+ character (len=64) :: fn
+ end function
+ end interface
+ character(kind=1, len=64) :: c(-3:-2,1:1,7:8), d(2:3,-7:-5)
+ character(kind = 1, len=1) :: e(2:4)
+ character(kind = 1, len=1+1) :: f(8:10,9:10)
+ integer :: i, j, k
+ c = ''
+ d = ''
+ e = '0'
+ f = '00'
+!$omp parallel do reduction (foo : c) reduction (bar : d) &
+!$omp & reduction (baz : e, f) private (j, k)
+ do i = 1, 64
+ forall (j = -3:-2, k = 7:8) &
+ c(j,1,k) = trim(c(j,1,k)) // char (ichar ('0') + i)
+ d = char (ichar ('0') + i) // d
+ e = char (ichar (e) + mod (i, 3))
+ f = char (ichar (f(:,:)(1:1)) + mod (i, 2)) &
+& // char (ichar (f(:,:)(2:2)) + mod (i, 3))
+ end do
+ do i = 1, 64
+ if (any (index (c, char (ichar ('0') + i)) .eq. 0)) call abort
+ if (any (index (d, char (ichar ('0') + i)) .eq. 0)) call abort
+ end do
+ if (any (e.ne.char (ichar ('0') + 64))) call abort
+ if (any (f(:,:)(1:1).ne.char (ichar ('0') + 32))) call abort
+ if (any (f(:,:)(2:2).ne.char (ichar ('0') + 64))) call abort
+end
+elemental function fn (x, y)
+ character (len=64), intent (in) :: x, y
+ character (len=64) :: fn
+ fn = trim(x) // y
+end function
diff --git a/libgomp/testsuite/libgomp.fortran/udr5.f90 b/libgomp/testsuite/libgomp.fortran/udr5.f90
new file mode 100644
index 00000000000..6dae9b9b816
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr5.f90
@@ -0,0 +1,57 @@
+! { dg-do run }
+
+module m
+ interface operator(.add.)
+ module procedure do_add
+ end interface
+ type dt
+ real :: r = 0.0
+ end type
+contains
+ function do_add(x, y)
+ type (dt), intent (in) :: x, y
+ type (dt) :: do_add
+ do_add%r = x%r + y%r
+ end function
+ subroutine dp_add(x, y)
+ double precision :: x, y
+ x = x + y
+ end subroutine
+ subroutine dp_init(x)
+ double precision :: x
+ x = 0.0
+ end subroutine
+end module
+
+program udr5
+ use m, only : operator(.add.), dt, dp_add, dp_init
+ type(dt) :: xdt, one
+ real :: r
+ integer (kind = 4) :: i4
+ integer (kind = 8) :: i8
+ real (kind = 4) :: r4
+ double precision :: dp
+!$omp declare reduction(.add.:dt:omp_out=omp_out.add.omp_in)
+!$omp declare reduction(foo:integer(4),integer(kind=8),real (kind = 4) &
+!$omp & :omp_out = omp_out + omp_in) initializer (omp_priv = 0)
+!$omp declare reduction(foo:double precision:dp_add (omp_out, omp_in)) &
+!$omp & initializer (dp_init (omp_priv))
+
+ one%r = 1.0
+ r = 0.0
+ i4 = 0
+ i8 = 0
+ r4 = 0.0
+ call dp_init (dp)
+!$omp parallel reduction(.add.: xdt) reduction(+: r) &
+!$omp & reduction(foo: i4, i8, r4, dp)
+ xdt = xdt.add.one
+ r = r + 1.0
+ i4 = i4 + 1
+ i8 = i8 + 1
+ r4 = r4 + 1.0
+ call dp_add (dp, 1.0d0)
+!$omp end parallel
+ if (xdt%r .ne. r) call abort
+ if (i4.ne.r.or.i8.ne.r.or.r4.ne.r.or.dp.ne.r) call abort
+end program udr5
diff --git a/libgomp/testsuite/libgomp.fortran/udr6.f90 b/libgomp/testsuite/libgomp.fortran/udr6.f90
new file mode 100644
index 00000000000..20736fb79db
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr6.f90
@@ -0,0 +1,69 @@
+! { dg-do run }
+
+module m
+ interface operator(.add.)
+ module procedure do_add
+ end interface
+ type dt
+ real :: r = 0.0
+ end type
+contains
+ elemental function do_add(x, y)
+ type (dt), intent (in) :: x, y
+ type (dt) :: do_add
+ do_add%r = x%r + y%r
+ end function
+ elemental subroutine dp_add(x, y)
+ double precision, intent (inout) :: x
+ double precision, intent (in) :: y
+ x = x + y
+ end subroutine
+ elemental subroutine dp_init(x)
+ double precision, intent (out) :: x
+ x = 0.0
+ end subroutine
+end module
+
+program udr6
+ use m, only : operator(.add.), dt, dp_add, dp_init
+ type(dt), allocatable :: xdt(:)
+ type(dt) :: one
+ real :: r
+ integer (kind = 4), allocatable, dimension(:) :: i4
+ integer (kind = 8), allocatable, dimension(:,:) :: i8
+ integer :: i
+ real (kind = 4), allocatable :: r4(:,:)
+ double precision, allocatable :: dp(:)
+!$omp declare reduction(.add.:dt:omp_out=omp_out.add.omp_in)
+!$omp declare reduction(foo:integer(4),integer(kind=8),real (kind = 4) &
+!$omp & :omp_out = omp_out + omp_in) initializer (omp_priv = 0)
+!$omp declare reduction(foo:double precision:dp_add (omp_out, omp_in)) &
+!$omp & initializer (dp_init (omp_priv))
+
+ one%r = 1.0
+ allocate (xdt(4), i4 (3), i8(-5:-2,2:3), r4(2:5,1:1), dp(7))
+ r = 0.0
+ i4 = 0
+ i8 = 0
+ r4 = 0.0
+ do i = 1, 7
+ call dp_init (dp(i))
+ end do
+!$omp parallel reduction(.add.: xdt) reduction(+: r) &
+!$omp & reduction(foo: i4, i8, r4, dp) private(i)
+ do i = 1, 4
+ xdt(i) = xdt(i).add.one
+ end do
+ r = r + 1.0
+ i4 = i4 + 1
+ i8 = i8 + 1
+ r4 = r4 + 1.0
+ do i = 1, 7
+ call dp_add (dp(i), 1.0d0)
+ end do
+!$omp end parallel
+ if (any (xdt%r .ne. r)) call abort
+ if (any (i4.ne.r).or.any(i8.ne.r)) call abort
+ if (any(r4.ne.r).or.any(dp.ne.r)) call abort
+ deallocate (xdt, i4, i8, r4, dp)
+end program udr6
diff --git a/libgomp/testsuite/libgomp.fortran/udr7.f90 b/libgomp/testsuite/libgomp.fortran/udr7.f90
new file mode 100644
index 00000000000..42be00c3a16
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr7.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+
+program udr7
+ implicit none
+ interface
+ elemental subroutine omp_priv (x, y, z)
+ real, intent (in) :: x
+ real, intent (inout) :: y
+ real, intent (in) :: z
+ end subroutine omp_priv
+ elemental real function omp_orig (x)
+ real, intent (in) :: x
+ end function omp_orig
+ end interface
+!$omp declare reduction (omp_priv : real : &
+!$omp & omp_priv (omp_orig (omp_in), omp_out, 1.0)) &
+!$omp & initializer (omp_out (omp_priv, omp_in (omp_orig)))
+ real :: x (2:4, 1:1, -2:0)
+ integer :: i
+ x = 0
+!$omp parallel do reduction (omp_priv : x)
+ do i = 1, 64
+ x = x + i
+ end do
+ if (any (x /= 2080.0)) call abort
+contains
+ elemental subroutine omp_out (x, y)
+ real, intent (out) :: x
+ real, intent (in) :: y
+ x = y - 4.0
+ end subroutine omp_out
+ elemental real function omp_in (x)
+ real, intent (in) :: x
+ omp_in = x + 4.0
+ end function omp_in
+end program udr7
+elemental subroutine omp_priv (x, y, z)
+ real, intent (in) :: x
+ real, intent (inout) :: y
+ real, intent (in) :: z
+ y = y + (x - 4.0) + (z - 1.0)
+end subroutine omp_priv
+elemental real function omp_orig (x)
+ real, intent (in) :: x
+ omp_orig = x + 4.0
+end function omp_orig
diff --git a/libgomp/testsuite/libgomp.fortran/udr8.f90 b/libgomp/testsuite/libgomp.fortran/udr8.f90
new file mode 100644
index 00000000000..9ef48a5c787
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr8.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+
+module udr8m1
+ integer, parameter :: a = 6
+ integer :: b
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in)
+!$omp declare reduction (.add. : integer : &
+!$omp & omp_out = omp_out .add. iand (omp_in, -4)) &
+!$omp & initializer (omp_priv = 3)
+ interface operator (.add.)
+ module procedure f1
+ end interface
+contains
+ integer function f1 (x, y)
+ integer, intent (in) :: x, y
+ f1 = x + y
+ end function f1
+end module udr8m1
+module udr8m2
+ use udr8m1
+ type dt
+ integer :: x
+ end type
+!$omp declare reduction (+ : dt : omp_out = omp_out + omp_in) &
+!$omp & initializer (omp_priv = dt (0))
+ interface operator (+)
+ module procedure f2
+ end interface
+contains
+ type(dt) function f2 (x, y)
+ type(dt), intent (in) :: x, y
+ f2%x = x%x + y%x
+ end function f2
+end module udr8m2
+ use udr8m2
+ integer :: i, j
+ type(dt) :: d
+ j = 3
+ d%x = 0
+!$omp parallel do reduction (.add.: j) reduction (+ : d)
+ do i = 1, 100
+ j = j.add.iand (i, -4)
+ d = d + dt(i)
+ end do
+ if (d%x /= 5050 .or. j /= 4903) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/udr9.f90 b/libgomp/testsuite/libgomp.fortran/udr9.f90
new file mode 100644
index 00000000000..a4fec1337c2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/udr9.f90
@@ -0,0 +1,65 @@
+! { dg-do run }
+
+module udr9m1
+ integer, parameter :: a = 6
+ integer :: b
+!$omp declare reduction (foo : integer : combiner1 (omp_out, omp_in)) &
+!$omp & initializer (initializer1 (omp_priv, omp_orig))
+!$omp declare reduction (.add. : integer : &
+!$omp & combiner1 (omp_out, omp_in)) &
+!$omp & initializer (initializer1 (omp_priv, omp_orig))
+ interface operator (.add.)
+ module procedure f1
+ end interface
+contains
+ integer function f1 (x, y)
+ integer, intent (in) :: x, y
+ f1 = x + y
+ end function f1
+ elemental subroutine combiner1 (x, y)
+ integer, intent (inout) :: x
+ integer, intent (in) :: y
+ x = x + iand (y, -4)
+ end subroutine
+ subroutine initializer1 (x, y)
+ integer :: x, y
+ if (y .ne. 3) call abort
+ x = y
+ end subroutine
+end module udr9m1
+module udr9m2
+ use udr9m1
+ type dt
+ integer :: x
+ end type
+!$omp declare reduction (+ : dt : combiner2 (omp_in, omp_out)) &
+!$omp & initializer (initializer2 (omp_priv))
+ interface operator (+)
+ module procedure f2
+ end interface
+contains
+ type(dt) function f2 (x, y)
+ type(dt), intent (in) :: x, y
+ f2%x = x%x + y%x
+ end function f2
+ subroutine combiner2 (x, y)
+ type(dt) :: x, y
+ y = y + x
+ end subroutine combiner2
+ subroutine initializer2 (x)
+ type(dt), intent(out) :: x
+ x%x = 0
+ end subroutine initializer2
+end module udr9m2
+ use udr9m2
+ integer :: i, j
+ type(dt) :: d
+ j = 3
+ d%x = 0
+!$omp parallel do reduction (.add.: j) reduction (+ : d)
+ do i = 1, 100
+ j = j.add.iand (i, -4)
+ d = d + dt(i)
+ end do
+ if (d%x /= 5050 .or. j /= 4903) call abort
+end