--- /dev/null
+! { dg-do run }
+! PR fortran/86277
+!
+! Check proper detection of presence of optional array dummy arguments
+! for zero-sized actual array arguments or array constructors:
+! tests for REAL (as non-character intrinsic type) and empty derived type
+
+program test
+ implicit none
+ real, parameter :: m(0) = 42.
+ real, parameter :: n(1) = 23.
+ real :: x(0) = 1.
+ real :: z(1) = 2.
+ real :: w(0)
+ real, pointer :: p(:)
+ real, allocatable :: y(:)
+ integer :: k = 0, l = 0 ! Test/failure counter
+ type dt
+ ! Empty type
+ end type dt
+ type(dt), parameter :: t0(0) = dt()
+ type(dt), parameter :: t1(1) = dt()
+ type(dt) :: t2(0) = dt()
+ type(dt) :: t3(1) = dt()
+ type(dt) :: t4(0)
+ type(dt), allocatable :: tt(:)
+ !
+ allocate (p(0))
+ allocate (y(0))
+ allocate (tt(0))
+ call a0 ()
+ call a1 ()
+ call a2 ()
+ call a3 ()
+ call all_missing ()
+ print *, "Total tests:", k, " failed:", l
+contains
+ subroutine a0 ()
+ print *, "Variables as actual argument"
+ call i (m)
+ call i (n)
+ call i (x)
+ call i (w)
+ call i (y)
+ call i (p)
+ call j (t0)
+ call j (t1)
+ call j (t2)
+ call j (t3)
+ call j (t4)
+ call j (tt)
+ print *, "Array section as actual argument"
+ call i (m(1:0))
+ call i (n(1:0))
+ call i (x(1:0))
+ call i (w(1:0))
+ call i (z(1:0))
+ call i (p(1:0))
+ call j (t0(1:0))
+ call j (t1(1:0))
+ call j (t2(1:0))
+ call j (t3(1:0))
+ call j (t4(1:0))
+ call j (tt(1:0))
+ end subroutine a0
+ !
+ subroutine a1 ()
+ print *, "Explicit temporary as actual argument"
+ call i ((m))
+ call i ((n))
+ call i ((n(1:0)))
+ call i ((x))
+ call i ((w))
+ call i ((z(1:0)))
+ call i ((y))
+ call i ((p))
+ call i ((p(1:0)))
+ call j ((t0))
+ call j ((t1))
+ call j ((tt))
+ call j ((t1(1:0)))
+ call j ((tt(1:0)))
+ end subroutine a1
+ !
+ subroutine a2 ()
+ print *, "Array constructor as actual argument"
+ call i ([m])
+ call i ([n])
+ call i ([x])
+ call i ([w])
+ call i ([z])
+ call i ([m(1:0)])
+ call i ([n(1:0)])
+ call i ([m,n(1:0)])
+ call i ([x(1:0)])
+ call i ([w(1:0)])
+ call i ([z(1:0)])
+ call i ([y])
+ call i ([p])
+ call i ([y,y])
+ call i ([p,p])
+ call i ([y(1:0)])
+ call i ([p(1:0)])
+ call j ([t0])
+ call j ([t0,t0])
+ call j ([t1])
+ call j ([tt])
+ call j ([tt,tt])
+ call j ([t1(1:0)])
+ call j ([tt(1:0)])
+ end subroutine a2
+ !
+ subroutine a3 ()
+ print *, "Array constructor with type-spec as actual argument"
+ call i ([real:: ])
+ call i ([real:: 7])
+ call i ([real:: m])
+ call i ([real:: n])
+ call i ([real:: x])
+ call i ([real:: w])
+ call i ([real:: m(1:0)])
+ call i ([real:: n(1:0)])
+ call i ([real:: m,n(1:0)])
+ call i ([real:: x(1:0)])
+ call i ([real:: w(1:0)])
+ call i ([real:: z(1:0)])
+ call i ([real:: y])
+ call i ([real:: p])
+ call i ([real:: y,y])
+ call i ([real:: p,p])
+ call i ([real:: y(1:0)])
+ call i ([real:: p(1:0)])
+ call j ([ dt :: ])
+ call j ([ dt :: t0])
+ call j ([ dt :: t0,t0])
+ call j ([ dt :: t1])
+ call j ([ dt :: tt])
+ call j ([ dt :: tt,tt])
+ call j ([ dt :: t1(1:0)])
+ call j ([ dt :: tt(1:0)])
+ end subroutine a3
+ !
+ subroutine i (arg)
+ real, optional, intent(in) :: arg(:)
+ logical :: t
+ t = present (arg)
+ k = k + 1
+ print *, 'test', k, merge (" ok", "FAIL", t)
+ if (.not. t) l = l + 1
+ if (.not. t) stop k
+ end subroutine i
+ !
+ subroutine j (arg)
+ type(dt), optional, intent(in) :: arg(:)
+ logical :: t
+ t = present (arg)
+ k = k + 1
+ print *, 'test', k, merge (" ok", "FAIL", t)
+ if (.not. t) l = l + 1
+ if (.not. t) stop k
+ end subroutine j
+ !
+ subroutine all_missing (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+ real, optional, intent(in) :: arg1(:)
+ real, optional, allocatable :: arg2(:)
+ real, optional, pointer :: arg3(:)
+ character(*), optional, intent(in) :: arg4(:)
+ character(*), optional, allocatable :: arg5(:)
+ character(*), optional, pointer :: arg6(:)
+ character(:), optional, pointer :: arg7(:)
+ character(:), optional, allocatable :: arg8(:)
+ if (present (arg1)) stop 101
+ if (present (arg2)) stop 102
+ if (present (arg3)) stop 103
+ if (present (arg4)) stop 104
+ if (present (arg5)) stop 105
+ if (present (arg6)) stop 106
+ if (present (arg7)) stop 107
+ if (present (arg8)) stop 108
+ end subroutine all_missing
+end program
--- /dev/null
+! { dg-do run }
+! PR fortran/86277
+!
+! Check proper detection of presence of optional array dummy arguments
+! for zero-sized actual array arguments or array constructors:
+! tests for CHARACTER
+
+program test
+ implicit none
+ character(0), parameter :: c0(0) = ""
+ character(0), parameter :: c1(1) = ""
+ character(1), parameter :: d0(0) = ""
+ character(1), parameter :: d1(1) = ""
+ character(0) :: w0(0)
+ character(0) :: w1(1)
+ character(:), allocatable :: cc(:)
+ integer :: k = 0, l = 0 ! Test/failure counter
+ !
+ allocate (character(0) :: cc(0))
+ call a0 ()
+ call a1 ()
+ call a2 ()
+ call a3 ()
+ print *, "Total tests:", k, " failed:", l
+contains
+ subroutine a0 ()
+ print *, "Variables as actual argument"
+ call i (c0)
+ call i (c1)
+ call i (d0)
+ call i (d1)
+ call i (w0)
+ call i (w1)
+ call i (cc)
+ print *, "Array section as actual argument"
+ call i (c1(1:0))
+ call i (c1(1:0)(1:0))
+ call i (w1(1:0))
+ call i (w1(1:0)(1:0))
+ call i (cc(1:0))
+ call i (cc(1:0)(1:0))
+ end subroutine a0
+ !
+ subroutine a1 ()
+ print *, "Explicit temporary as actual argument"
+ call i ((c0))
+ call i ((c1))
+ call i ((d0))
+ call i ((d1))
+ call i ((w0))
+ call i ((w1))
+ call i ((cc))
+ call i ((c1(1:0)))
+ call i ((c1(1:0)(1:0)))
+ call i ((w1(1:0)))
+ call i ((w1(1:0)(1:0)))
+ call i ((cc(1:0)))
+ call i ((cc(1:0)(1:0)))
+ end subroutine a1
+ !
+ subroutine a2 ()
+ print *, "Array constructor as actual argument"
+ call i ([c0])
+ call i ([c1])
+ call i ([d0])
+ call i ([d1])
+ call i ([w0])
+ call i ([w1])
+ call i ([cc])
+ call i ([c0,c0])
+ call i ([c1,c1])
+ call i ([d0,d0])
+ call i ([cc,cc])
+ call i ([c1(1:0)])
+ call i ([c1(1:0)(1:0)])
+ call i ([w1(1:0)])
+ call i ([w1(1:0)(1:0)])
+ call i ([cc(1:0)])
+ call i ([cc(1:0)(1:0)])
+ end subroutine a2
+ !
+ subroutine a3 ()
+ print *, "Array constructor with type-spec as actual argument"
+ call i ([character(0) :: ])
+ call i ([character(0) :: ""])
+ call i ([character(0) :: c0])
+ call i ([character(0) :: c1])
+ call i ([character(0) :: d0])
+ call i ([character(0) :: d1])
+ call i ([character(0) :: w0])
+ call i ([character(0) :: w1])
+ call i ([character(0) :: cc])
+ call i ([character(0) :: c0,c0])
+ call i ([character(0) :: c1,c1])
+ call i ([character(0) :: d0,d0])
+ call i ([character(0) :: cc,cc])
+ call i ([character(0) :: c1(1:0)])
+ call i ([character(0) :: c1(1:0)(1:0)])
+ call i ([character(0) :: w1(1:0)])
+ call i ([character(0) :: w1(1:0)(1:0)])
+ call i ([character(0) :: cc(1:0)])
+ call i ([character(0) :: cc(1:0)(1:0)])
+ end subroutine a3
+ !
+ subroutine i(arg)
+ character(*), optional, intent(in) :: arg(:)
+ logical :: t
+ t = present (arg)
+ k = k + 1
+ print *, 'test', k, merge (" ok", "FAIL", t)
+ if (.not. t) l = l + 1
+ if (.not. t) stop k
+ end subroutine i
+end program