public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Peter Hill <peter.hill@york.ac.uk>
To: gcc-patches@gcc.gnu.org
Cc: fortran@gcc.gnu.org
Subject: [PATCH] Fortran: fix passing array component to polymorphic argument [PR105658]
Date: Thu, 15 Feb 2024 17:50:51 +0000	[thread overview]
Message-ID: <CAFmps265e6DURKbU2+nMJBtSvb+-w-RHnFE_0ozqDWE0fzRFPQ@mail.gmail.com> (raw)

Dear all,

The attached patch fixes PR105658 by forcing an array temporary to be
created. This is required when passing an array component, but this
didn't happen if the dummy argument was an unlimited polymorphic type.

The problem bit of code is in `gfc_conv_expr_descriptor`, near L7828:

      subref_array_target = (is_subref_array (expr)
     && (se->direct_byref
|| expr->ts.type == BT_CHARACTER));
      need_tmp = (gfc_ref_needs_temporary_p (expr->ref)
  && !subref_array_target);

where `need_tmp` is being evaluated to 0.  The logic here isn't clear
to me, and this function is used in several places, which is why I
went with setting `parmse.force_tmp = 1` in `gfc_conv_procedure_call`
and using the same conditional as the later branch for the
non-polymorphic case (near the call to `gfc_conv_subref_array_arg`)

If this patch is ok, please could someone commit it for me? This is my
first patch for GCC, so apologies in advance if the commit message is
missing something.

Tested on x86_64-pc-linux-gnu.

The bug is present in gfortran back to 4.9, so should it also be backported?

Cheers,
Peter

         PR fortran/105658

gcc/fortran/ChangeLog

        * trans-expr.cc (gfc_conv_procedure_call): When passing an
        array component reference of intrinsic type to a procedure
        with an unlimited polymorphic dummy argument, a temporary
        should be created.

gcc/testsuite/ChangeLog

        * gfortran.dg/PR105658.f90: New test.
---
 gcc/fortran/trans-expr.cc              |  8 ++++++++
 gcc/testsuite/gfortran.dg/PR105658.f90 | 25 +++++++++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/PR105658.f90

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index a0593b76f18..7fd3047c4e9 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6439,6 +6439,14 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
       CLASS object for the unlimited polymorphic formal.  */
    gfc_find_vtab (&e->ts);
    gfc_init_se (&parmse, se);
+   /* The actual argument is a component reference to an array
+      of derived types, so we need to force creation of a
+      temporary */
+   if (e->expr_type == EXPR_VARIABLE
+       && is_subref_array (e)
+       && !(fsym && fsym->attr.pointer))
+     parmse.force_tmp = 1;
+
    gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);

  }
diff --git a/gcc/testsuite/gfortran.dg/PR105658.f90
b/gcc/testsuite/gfortran.dg/PR105658.f90
new file mode 100644
index 00000000000..407ee25f77c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR105658.f90
@@ -0,0 +1,25 @@
+! { dg-do compile }
+! { dg-options "-Warray-temporaries" }
+! Test fix for incorrectly passing array component to unlimited
polymorphic procedure
+
+module test_PR105658_mod
+  implicit none
+  type :: foo
+    integer :: member1
+    integer :: member2
+  end type foo
+contains
+  subroutine print_poly(array)
+    class(*), dimension(:), intent(in) :: array
+    select type(array)
+    type is (integer)
+      print*, array
+    end select
+  end subroutine print_poly
+
+  subroutine do_print(thing)
+    type(foo), dimension(3), intent(in) :: thing
+    call print_poly(thing%member1) ! { dg-warning "array temporary" }
+  end subroutine do_print
+
+end module test_PR105658_mod
-- 
2.43.0

             reply	other threads:[~2024-02-15 17:51 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-15 17:50 Peter Hill [this message]
2024-02-16 21:19 ` Harald Anlauf
2024-02-19 15:19   ` Peter Hill
2024-02-19 19:52     ` Harald Anlauf
2024-02-20 19:53     ` Harald Anlauf
2024-02-20 20:09       ` Steve Kargl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFmps265e6DURKbU2+nMJBtSvb+-w-RHnFE_0ozqDWE0fzRFPQ@mail.gmail.com \
    --to=peter.hill@york.ac.uk \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).