* [PATCH] Fortran: fix passing of zero-sized array arguments to procedures [PR86277]
@ 2023-06-12 21:12 Harald Anlauf
2023-06-13 17:45 ` Steve Kargl
0 siblings, 1 reply; 4+ messages in thread
From: Harald Anlauf @ 2023-06-12 21:12 UTC (permalink / raw)
To: fortran, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 937 bytes --]
Dear all,
the attached - actually rather small - patch is the result of a
rather intensive session with Mikael in an attempt to fix the
situation that we did not create proper temporaries when passing
zero-sized array arguments to procedures. When the dummy argument
was declared as OPTIONAL, in many cases it was mis-detected as
non-present. This also depended on the type of argument, and
was different for different intrinsic types, notably character,
and derived types, and should explain the rather large ratio of
the size of the provided testcases to the actual fix...
(What the patch does not address: we still generate too much code
for unneeded temporaries, often two temporaries instead of just
one. I'll open a separate PR to track this.)
Regtested on x86_64-pc-linux-gnu. OK for mainline?
If this survives long enough on 14-trunk, would this be eligible
for a backport to 13-branch in time for 13.2?
Thanks,
Harald
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pr86277.diff --]
[-- Type: text/x-patch, Size: 10336 bytes --]
From 773b2aae412145d61638a0423c5891c4dfd0f945 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Mon, 12 Jun 2023 23:08:48 +0200
Subject: [PATCH] Fortran: fix passing of zero-sized array arguments to
procedures [PR86277]
gcc/fortran/ChangeLog:
PR fortran/86277
* trans-array.cc (gfc_trans_allocate_array_storage): When passing a
zero-sized array with fixed (= non-dynamic) size, allocate temporary
by the caller, not by the callee.
gcc/testsuite/ChangeLog:
PR fortran/86277
* gfortran.dg/zero_sized_14.f90: New test.
* gfortran.dg/zero_sized_15.f90: New test.
Co-authored-by: Mikael Morin <mikael@gcc.gnu.org>
---
gcc/fortran/trans-array.cc | 2 +-
gcc/testsuite/gfortran.dg/zero_sized_14.f90 | 181 ++++++++++++++++++++
gcc/testsuite/gfortran.dg/zero_sized_15.f90 | 114 ++++++++++++
3 files changed, 296 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gfortran.dg/zero_sized_14.f90
create mode 100644 gcc/testsuite/gfortran.dg/zero_sized_15.f90
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index e1c75e9fe02..e7c51bae052 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1117,7 +1117,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
desc = info->descriptor;
info->offset = gfc_index_zero_node;
- if (size == NULL_TREE || integer_zerop (size))
+ if (size == NULL_TREE || (dynamic && integer_zerop (size)))
{
/* A callee allocated array. */
gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
diff --git a/gcc/testsuite/gfortran.dg/zero_sized_14.f90 b/gcc/testsuite/gfortran.dg/zero_sized_14.f90
new file mode 100644
index 00000000000..32c7ae28e3a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/zero_sized_14.f90
@@ -0,0 +1,181 @@
+! { 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
diff --git a/gcc/testsuite/gfortran.dg/zero_sized_15.f90 b/gcc/testsuite/gfortran.dg/zero_sized_15.f90
new file mode 100644
index 00000000000..c7d12ae7173
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/zero_sized_15.f90
@@ -0,0 +1,114 @@
+! { 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
--
2.35.3
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Fortran: fix passing of zero-sized array arguments to procedures [PR86277]
2023-06-12 21:12 [PATCH] Fortran: fix passing of zero-sized array arguments to procedures [PR86277] Harald Anlauf
@ 2023-06-13 17:45 ` Steve Kargl
2023-06-13 19:33 ` Harald Anlauf
0 siblings, 1 reply; 4+ messages in thread
From: Steve Kargl @ 2023-06-13 17:45 UTC (permalink / raw)
To: Harald Anlauf via Fortran; +Cc: gcc-patches
On Mon, Jun 12, 2023 at 11:12:45PM +0200, Harald Anlauf via Fortran wrote:
> Dear all,
>
> the attached - actually rather small - patch is the result of a
> rather intensive session with Mikael in an attempt to fix the
> situation that we did not create proper temporaries when passing
> zero-sized array arguments to procedures. When the dummy argument
> was declared as OPTIONAL, in many cases it was mis-detected as
> non-present. This also depended on the type of argument, and
> was different for different intrinsic types, notably character,
> and derived types, and should explain the rather large ratio of
> the size of the provided testcases to the actual fix...
>
> (What the patch does not address: we still generate too much code
> for unneeded temporaries, often two temporaries instead of just
> one. I'll open a separate PR to track this.)
>
> Regtested on x86_64-pc-linux-gnu. OK for mainline?
>
> If this survives long enough on 14-trunk, would this be eligible
> for a backport to 13-branch in time for 13.2?
>
OK to commit.
I've reviewed the bugzilla exchange between Mikael and you,
and agree with committing this and opening a new PR to
track the unneeded temporaries issue.
--
Steve
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Fortran: fix passing of zero-sized array arguments to procedures [PR86277]
2023-06-13 17:45 ` Steve Kargl
@ 2023-06-13 19:33 ` Harald Anlauf
2023-06-13 19:33 ` Harald Anlauf
0 siblings, 1 reply; 4+ messages in thread
From: Harald Anlauf @ 2023-06-13 19:33 UTC (permalink / raw)
To: sgk, Harald Anlauf via Fortran; +Cc: gcc-patches
Hi Steve,
On 6/13/23 19:45, Steve Kargl via Gcc-patches wrote:
> On Mon, Jun 12, 2023 at 11:12:45PM +0200, Harald Anlauf via Fortran wrote:
>> Dear all,
>>
>> the attached - actually rather small - patch is the result of a
>> rather intensive session with Mikael in an attempt to fix the
>> situation that we did not create proper temporaries when passing
>> zero-sized array arguments to procedures. When the dummy argument
>> was declared as OPTIONAL, in many cases it was mis-detected as
>> non-present. This also depended on the type of argument, and
>> was different for different intrinsic types, notably character,
>> and derived types, and should explain the rather large ratio of
>> the size of the provided testcases to the actual fix...
>>
>> (What the patch does not address: we still generate too much code
>> for unneeded temporaries, often two temporaries instead of just
>> one. I'll open a separate PR to track this.)
>>
>> Regtested on x86_64-pc-linux-gnu. OK for mainline?
>>
>> If this survives long enough on 14-trunk, would this be eligible
>> for a backport to 13-branch in time for 13.2?
>>
>
> OK to commit.
>
> I've reviewed the bugzilla exchange between Mikael and you,
> and agree with committing this and opening a new PR to
> track the unneeded temporaries issue.
this is tracked here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110241
Thanks for the review!
Harald
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Fortran: fix passing of zero-sized array arguments to procedures [PR86277]
2023-06-13 19:33 ` Harald Anlauf
@ 2023-06-13 19:33 ` Harald Anlauf
0 siblings, 0 replies; 4+ messages in thread
From: Harald Anlauf @ 2023-06-13 19:33 UTC (permalink / raw)
To: gcc-patches; +Cc: fortran
Hi Steve,
On 6/13/23 19:45, Steve Kargl via Gcc-patches wrote:
> On Mon, Jun 12, 2023 at 11:12:45PM +0200, Harald Anlauf via Fortran wrote:
>> Dear all,
>>
>> the attached - actually rather small - patch is the result of a
>> rather intensive session with Mikael in an attempt to fix the
>> situation that we did not create proper temporaries when passing
>> zero-sized array arguments to procedures. When the dummy argument
>> was declared as OPTIONAL, in many cases it was mis-detected as
>> non-present. This also depended on the type of argument, and
>> was different for different intrinsic types, notably character,
>> and derived types, and should explain the rather large ratio of
>> the size of the provided testcases to the actual fix...
>>
>> (What the patch does not address: we still generate too much code
>> for unneeded temporaries, often two temporaries instead of just
>> one. I'll open a separate PR to track this.)
>>
>> Regtested on x86_64-pc-linux-gnu. OK for mainline?
>>
>> If this survives long enough on 14-trunk, would this be eligible
>> for a backport to 13-branch in time for 13.2?
>>
>
> OK to commit.
>
> I've reviewed the bugzilla exchange between Mikael and you,
> and agree with committing this and opening a new PR to
> track the unneeded temporaries issue.
this is tracked here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110241
Thanks for the review!
Harald
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-06-13 19:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-12 21:12 [PATCH] Fortran: fix passing of zero-sized array arguments to procedures [PR86277] Harald Anlauf
2023-06-13 17:45 ` Steve Kargl
2023-06-13 19:33 ` Harald Anlauf
2023-06-13 19:33 ` Harald Anlauf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).