aboutsummaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2021-02-22 13:20:26 +0100
committerTobias Burnus <tobias@codesourcery.com>2021-02-22 13:20:26 +0100
commite9b34037cdd196ab912a7ac3358f8a8d3e307e92 (patch)
treeb0e0acb1e2d51633ffd9d111637a0a663aa030e1 /libgomp
parent451002e626620833a57c35002ea9ac4e5ba7633a (diff)
downloadgcc-e9b34037cdd196ab912a7ac3358f8a8d3e307e92.zip
gcc-e9b34037cdd196ab912a7ac3358f8a8d3e307e92.tar.gz
gcc-e9b34037cdd196ab912a7ac3358f8a8d3e307e92.tar.bz2
Fortran/OpenMP: Fix optional dummy procedures [PR99171]
gcc/fortran/ChangeLog: PR fortran/99171 * trans-openmp.c (gfc_omp_is_optional_argument): Regard optional dummy procs as nonoptional as no special treatment is needed. libgomp/ChangeLog: PR fortran/99171 * testsuite/libgomp.fortran/dummy-procs-1.f90: New test.
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/testsuite/libgomp.fortran/dummy-procs-1.f90393
1 files changed, 393 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.fortran/dummy-procs-1.f90 b/libgomp/testsuite/libgomp.fortran/dummy-procs-1.f90
new file mode 100644
index 0000000..fcb17ce
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/dummy-procs-1.f90
@@ -0,0 +1,393 @@
+! { dg-do run }
+!
+! PR fortran/99171
+!
+! Check dummy procedure arguments, especially optional ones
+!
+module m
+ use iso_c_binding
+ implicit none (type, external)
+ integer :: cnt
+ integer :: cnt2
+contains
+ subroutine proc()
+ cnt = cnt + 1
+ end subroutine
+
+ subroutine proc2()
+ cnt2 = cnt2 + 1
+ end subroutine
+
+ subroutine check(my_proc)
+ procedure(proc) :: my_proc
+ cnt = 42
+ call my_proc()
+ if (cnt /= 43) stop 1
+
+ !$omp parallel
+ call my_proc()
+ !$omp end parallel
+ if (cnt <= 43) stop 2
+ end
+
+ subroutine check_opt(my_proc)
+ procedure(proc), optional :: my_proc
+ logical :: is_present
+ is_present = present(my_proc)
+ cnt = 55
+ if (present (my_proc)) then
+ call my_proc()
+ if (cnt /= 56) stop 3
+ endif
+
+ !$omp parallel
+ if (is_present .neqv. present (my_proc)) stop 4
+ if (present (my_proc)) then
+ call my_proc()
+ if (cnt <= 56) stop 5
+ end if
+ !$omp end parallel
+ if (is_present) then
+ if (cnt <= 56) stop 6
+ else if (cnt /= 55) then
+ stop 7
+ end if
+ end
+
+ subroutine check_ptr(my_proc)
+ procedure(proc), pointer :: my_proc
+ logical :: is_assoc
+ integer :: mycnt
+ is_assoc = associated (my_proc)
+
+ cnt = 10
+ cnt2 = 20
+ if (associated (my_proc)) then
+ call my_proc()
+ if (cnt /= 11 .or. cnt2 /= 20) stop 8
+ endif
+
+ !$omp parallel
+ if (is_assoc .neqv. associated (my_proc)) stop 9
+ if (associated (my_proc)) then
+ if (.not. associated (my_proc, proc)) stop 10
+ call my_proc()
+ if (cnt <= 11 .or. cnt2 /= 20) stop 11
+ else if (cnt /= 10 .or. cnt2 /= 20) then
+ stop 12
+ end if
+ !$omp end parallel
+ if (is_assoc .neqv. associated (my_proc)) stop 13
+ if (associated (my_proc)) then
+ if (cnt <= 11 .or. cnt2 /= 20) stop 14
+ else if (is_assoc .and. (cnt /= 11 .or. cnt2 /= 20)) then
+ stop 15
+ end if
+
+ cnt = 30
+ cnt2 = 40
+ mycnt = 0
+ !$omp parallel shared(mycnt)
+ !$omp critical
+ my_proc => proc2
+ if (.not.associated (my_proc, proc2)) stop 17
+ mycnt = mycnt + 1
+ call my_proc()
+ if (cnt2 /= 40 + mycnt .or. cnt /= 30) stop 18
+ !$omp end critical
+ !$omp end parallel
+ if (.not.associated (my_proc, proc2)) stop 19
+ if (cnt2 /= 40 + mycnt .or. cnt /= 30) stop 20
+ end
+
+ subroutine check_ptr_opt(my_proc)
+ procedure(proc), pointer, optional :: my_proc
+ logical :: is_assoc, is_present
+ integer :: mycnt
+ is_assoc = .false.
+ is_present = present(my_proc)
+
+ cnt = 10
+ cnt2 = 20
+ if (present (my_proc)) then
+ is_assoc = associated (my_proc)
+ if (associated (my_proc)) then
+ call my_proc()
+ if (cnt /= 11 .or. cnt2 /= 20) stop 21
+ endif
+ end if
+
+ !$omp parallel
+ if (is_present .neqv. present (my_proc)) stop 22
+ if (present (my_proc)) then
+ if (is_assoc .neqv. associated (my_proc)) stop 23
+ if (associated (my_proc)) then
+ if (.not. associated (my_proc, proc)) stop 24
+ call my_proc()
+ if (cnt <= 11 .or. cnt2 /= 20) stop 25
+ else if (cnt /= 10 .or. cnt2 /= 20) then
+ stop 26
+ end if
+ end if
+ !$omp end parallel
+ if (present (my_proc)) then
+ if (is_assoc .neqv. associated (my_proc)) stop 27
+ if (associated (my_proc)) then
+ if (cnt <= 11 .or. cnt2 /= 20) stop 28
+ else if (is_assoc .and. (cnt /= 11 .or. cnt2 /= 20)) then
+ stop 29
+ end if
+ end if
+
+ cnt = 30
+ cnt2 = 40
+ mycnt = 0
+ !$omp parallel shared(mycnt)
+ if (is_present .neqv. present (my_proc)) stop 30
+ !$omp critical
+ if (present (my_proc)) then
+ my_proc => proc2
+ if (.not.associated (my_proc, proc2)) stop 31
+ mycnt = mycnt + 1
+ call my_proc()
+ if (cnt2 /= 40 + mycnt .or. cnt /= 30) stop 32
+ end if
+ !$omp end critical
+ !$omp end parallel
+ if (present (my_proc)) then
+ if (.not.associated (my_proc, proc2)) stop 33
+ if (cnt2 /= 40 + mycnt .or. cnt /= 30) stop 34
+ end if
+ end
+
+ ! ----------------------
+
+ subroutine cfun_check(my_cfun)
+ type(c_funptr) :: my_cfun
+ procedure(proc), pointer :: pptr
+ logical :: has_cfun
+
+ has_cfun = c_associated (my_cfun)
+ pptr => null()
+ cnt = 42
+ call c_f_procpointer (my_cfun, pptr)
+ if (has_cfun) then
+ call pptr()
+ if (cnt /= 43) stop 35
+ end if
+
+ pptr => null()
+ !$omp parallel
+ if (has_cfun .neqv. c_associated (my_cfun)) stop 36
+ !$omp critical
+ call c_f_procpointer (my_cfun, pptr)
+ !$omp end critical
+ if (has_cfun) then
+ call pptr()
+ if (cnt <= 43) stop 37
+ else
+ if (associated (pptr)) stop 38
+ end if
+ !$omp end parallel
+ end
+
+ subroutine cfun_check_opt(my_cfun)
+ type(c_funptr), optional :: my_cfun
+ procedure(proc), pointer :: pptr
+ logical :: has_cfun, is_present
+
+ has_cfun = .false.
+ is_present = present (my_cfun)
+ if (is_present) has_cfun = c_associated (my_cfun)
+
+ cnt = 1
+ pptr => null()
+ !$omp parallel
+ if (is_present .neqv. present (my_cfun)) stop 39
+ if (is_present) then
+ if (has_cfun .neqv. c_associated (my_cfun, c_funloc(proc))) stop 40
+ !$omp critical
+ call c_f_procpointer (my_cfun, pptr)
+ !$omp end critical
+ if (has_cfun) then
+ call pptr()
+ if (cnt <= 1) stop 41
+ else
+ if (associated (pptr)) stop 42
+ end if
+ end if
+ !$omp end parallel
+ end
+
+ subroutine cfun_check_ptr(my_cfun)
+ type(c_funptr), pointer :: my_cfun
+ procedure(proc), pointer :: pptr
+ logical :: has_cfun, is_assoc
+
+ has_cfun = .false.
+ is_assoc = associated (my_cfun)
+ if (is_assoc) has_cfun = c_associated (my_cfun)
+
+ cnt = 1
+ pptr => null()
+ !$omp parallel
+ if (is_assoc .neqv. associated (my_cfun)) stop 43
+ if (is_assoc) then
+ if (has_cfun .neqv. c_associated (my_cfun, c_funloc(proc))) stop 44
+ !$omp critical
+ call c_f_procpointer (my_cfun, pptr)
+ !$omp end critical
+ if (has_cfun) then
+ call pptr()
+ if (cnt <= 1) stop 45
+ else
+ if (associated (pptr)) stop 46
+ end if
+ end if
+ !$omp end parallel
+
+ cnt = 42
+ cnt2 = 1
+ pptr => null()
+ !$omp parallel
+ if (is_assoc .neqv. associated (my_cfun)) stop 47
+ if (is_assoc) then
+ !$omp critical
+ my_cfun = c_funloc (proc2)
+ call c_f_procpointer (my_cfun, pptr)
+ !$omp end critical
+ if (.not. associated (pptr, proc2)) stop 48
+ if (.not. c_associated (my_cfun, c_funloc(proc2))) stop 49
+ call pptr()
+ if (cnt /= 42 .or. cnt2 <= 1) stop 50
+ end if
+ !$omp end parallel
+ if (is_assoc) then
+ if (.not. associated (pptr, proc2)) stop 51
+ if (.not. c_associated (my_cfun, c_funloc(proc2))) stop 52
+ else
+ if (associated (pptr)) stop 53
+ end if
+ end
+
+ subroutine cfun_check_ptr_opt (my_cfun)
+ type(c_funptr), pointer, optional :: my_cfun
+ procedure(proc), pointer :: pptr
+ logical :: is_present, has_cfun, is_assoc
+
+ has_cfun = .false.
+ is_assoc = .false.
+ is_present = present (my_cfun)
+ if (is_present) then
+ is_assoc = associated (my_cfun)
+ if (is_assoc) has_cfun = c_associated (my_cfun)
+ end if
+
+ cnt = 1
+ pptr => null()
+ !$omp parallel
+ if (is_present .neqv. present (my_cfun)) stop 54
+ if (is_present) then
+ if (is_assoc .neqv. associated (my_cfun)) stop 55
+ if (is_assoc) then
+ if (has_cfun .neqv. c_associated (my_cfun, c_funloc(proc))) stop 56
+ !$omp critical
+ call c_f_procpointer (my_cfun, pptr)
+ !$omp end critical
+ if (has_cfun) then
+ call pptr()
+ if (cnt <= 1) stop 57
+ else
+ if (associated (pptr)) stop 58
+ end if
+ end if
+ end if
+ !$omp end parallel
+
+ cnt = 42
+ cnt2 = 1
+ pptr => null()
+ !$omp parallel
+ if (is_present .neqv. present (my_cfun)) stop 59
+ if (is_present) then
+ if (is_assoc .neqv. associated (my_cfun)) stop 60
+ if (is_assoc) then
+ !$omp critical
+ my_cfun = c_funloc (proc2)
+ call c_f_procpointer (my_cfun, pptr)
+ !$omp end critical
+ if (.not. associated (pptr, proc2)) stop 61
+ if (.not. c_associated (my_cfun, c_funloc(proc2))) stop 62
+ call pptr()
+ if (cnt /= 42 .or. cnt2 <= 1) stop 63
+ end if
+ end if
+ !$omp end parallel
+ if (is_present .and. is_assoc) then
+ if (.not. associated (pptr, proc2)) stop 64
+ if (.not. c_associated (my_cfun, c_funloc(proc2))) stop 65
+ else
+ if (associated (pptr)) stop 66
+ end if
+ end
+end module m
+
+
+
+program main
+ use m
+ implicit none (type, external)
+ procedure(proc), pointer :: pptr
+ type(c_funptr), target :: cfun
+ type(c_funptr), pointer :: cfun_ptr
+
+ call check(proc)
+ call check_opt()
+ call check_opt(proc)
+
+ pptr => null()
+ call check_ptr(pptr)
+ pptr => proc
+ call check_ptr(pptr)
+
+ call check_ptr_opt()
+ pptr => null()
+ call check_ptr_opt(pptr)
+ pptr => proc
+ call check_ptr_opt(pptr)
+
+ ! -------------------
+ pptr => null()
+
+ cfun = c_funloc (pptr)
+ call cfun_check(cfun)
+
+ cfun = c_funloc (proc)
+ call cfun_check(cfun)
+
+ call cfun_check_opt()
+
+ cfun = c_funloc (pptr)
+ call cfun_check_opt(cfun)
+
+ cfun = c_funloc (proc)
+ call cfun_check_opt(cfun)
+
+ ! - - - -
+ cfun_ptr => null()
+ call cfun_check_ptr (cfun_ptr)
+
+ cfun = c_funloc (proc)
+ cfun_ptr => cfun
+ call cfun_check_ptr (cfun_ptr)
+
+ ! - - - -
+ call cfun_check_ptr_opt ()
+
+ cfun_ptr => null()
+ call cfun_check_ptr_opt (cfun_ptr)
+
+ cfun = c_funloc (proc)
+ cfun_ptr => cfun
+ call cfun_check_ptr_opt (cfun_ptr)
+end program