public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Mikael Morin <mikael@gcc.gnu.org>
To: fortran@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: [PATCH 2/3] fortran: Fix length one character dummy arg type [PR110419]
Date: Wed,  9 Aug 2023 22:21:21 +0200	[thread overview]
Message-ID: <20230809202122.695376-3-mikael@gcc.gnu.org> (raw)
In-Reply-To: <20230809202122.695376-1-mikael@gcc.gnu.org>

Revision r14-2171-g8736d6b14a4dfdfb58c80ccd398981b0fb5d00aa
changed the argument passing convention for length 1 value dummy
arguments to pass just the single character by value.  However, the
procedure declarations weren't updated to reflect the change in the
argument types.
This change does the missing argument type update.

The change of argument types generated an internal error in
gfc_conv_string_parameter with value_9.f90.  Indeed, that function is
not prepared for bare character type, so it is updated as well.

The condition guarding the single character argument passing code
is loosened to not exclude non-interoperable kind (this fixes
a regression with c_char_tests_2.f03).

Finally, the constant string argument passing code is updated as well
to extract the single char and pass it instead of passing it as
a length one string.  As the code taking care of non-constant arguments
was already doing this, the condition guarding it is just removed.

With these changes, value_9.f90 passes on 32 bits big-endian powerpc.

	PR fortran/110360
	PR fortran/110419

gcc/fortran/ChangeLog:

	* trans-types.cc (gfc_sym_type): Use a bare character type for length
	one value character dummy arguments.
	* trans-expr.cc (gfc_conv_string_parameter): Handle single character
	case.
	(gfc_conv_procedure_call): Don't exclude interoperable kinds
	from single character handling.  For single character dummy arguments,
	extend the existing handling of non-constant expressions to constant
	expressions.

gcc/testsuite/ChangeLog:

	* gfortran.dg/bind_c_usage_13.f03: Update tree dump patterns.
---
 gcc/fortran/trans-expr.cc                     | 35 +++++++++++--------
 gcc/fortran/trans-types.cc                    |  5 ++-
 gcc/testsuite/gfortran.dg/bind_c_usage_13.f03 |  8 ++---
 3 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 6da3975f77c..d91cc9da221 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6451,26 +6451,24 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
 		    /* ABI: actual arguments to CHARACTER(len=1),VALUE
 		       dummy arguments are actually passed by value.
-		       Strings are truncated to length 1.
-		       The BIND(C) case is handled elsewhere.  */
-		    if (!fsym->ts.is_c_interop
-			&& gfc_length_one_character_type_p (&fsym->ts))
+		       Strings are truncated to length 1.  */
+		    if (gfc_length_one_character_type_p (&fsym->ts))
 		      {
-			if (e->expr_type != EXPR_CONSTANT)
-			  {
-			    tree slen1 = build_int_cst (gfc_charlen_type_node, 1);
-			    gfc_conv_string_parameter (&parmse);
-			    parmse.expr = gfc_string_to_single_character (slen1,
-									  parmse.expr,
-									  e->ts.kind);
-			    /* Truncate resulting string to length 1.  */
-			    parmse.string_length = slen1;
-			  }
-			else if (e->value.character.length > 1)
+			if (e->expr_type == EXPR_CONSTANT
+			    && e->value.character.length > 1)
 			  {
 			    e->value.character.length = 1;
 			    gfc_conv_expr (&parmse, e);
 			  }
+
+			tree slen1 = build_int_cst (gfc_charlen_type_node, 1);
+			gfc_conv_string_parameter (&parmse);
+			parmse.expr
+			    = gfc_string_to_single_character (slen1,
+							      parmse.expr,
+							      e->ts.kind);
+			/* Truncate resulting string to length 1.  */
+			parmse.string_length = slen1;
 		      }
 
 		    if (fsym->attr.optional
@@ -10610,6 +10608,13 @@ gfc_conv_string_parameter (gfc_se * se)
 {
   tree type;
 
+  if (TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE
+      && integer_onep (se->string_length))
+    {
+      se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
+      return;
+    }
+
   if (TREE_CODE (se->expr) == STRING_CST)
     {
       type = TREE_TYPE (TREE_TYPE (se->expr));
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 987e3d26c46..084b8c3ae2c 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2313,7 +2313,10 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
 	      && sym->ns->proc_name
 	      && sym->ns->proc_name->attr.is_bind_c)
 	  || (sym->ts.deferred && (!sym->ts.u.cl
-				   || !sym->ts.u.cl->backend_decl))))
+				   || !sym->ts.u.cl->backend_decl))
+	  || (sym->attr.dummy
+	      && sym->attr.value
+	      && gfc_length_one_character_type_p (&sym->ts))))
     type = gfc_get_char_type (sym->ts.kind);
   else
     type = gfc_typenode_for_spec (&sym->ts, sym->attr.codimension);
diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_13.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_13.f03
index 470bd59ed38..3cc9f8e0fe9 100644
--- a/gcc/testsuite/gfortran.dg/bind_c_usage_13.f03
+++ b/gcc/testsuite/gfortran.dg/bind_c_usage_13.f03
@@ -130,9 +130,9 @@ end program test
 ! { dg-final { scan-tree-dump "multiso .&.v..1..lb: 1 sz: 1., &.x..1..lb: 1 sz: 1..;" "original" } }
 ! { dg-final { scan-tree-dump "multiso2 .&.w..1..lb: 1 sz: 1., &.x..1..lb: 1 sz: 1..;" "original" } }
 !
-! { dg-final { scan-tree-dump "mult_val ..x., .x., 1, 1.;" "original" } }
+! { dg-final { scan-tree-dump "mult_val .120, 120, 1, 1.;" "original" } }
 ! { dg-final { scan-tree-dump "multiso_val .121, 120.;" "original" } }
-! { dg-final { scan-tree-dump "multiso2_val ..z., .x..;" "original" } }
+! { dg-final { scan-tree-dump "multiso2_val .122, 120.;" "original" } }
 !
 ! Single argument dump:
 !
@@ -144,7 +144,7 @@ end program test
 ! { dg-final { scan-tree-dump "subiso .&.v..1..lb: 1 sz: 1..;" "original" } }
 ! { dg-final { scan-tree-dump "subiso2 .&.w..1..lb: 1 sz: 1..;" "original" } }
 !
-! { dg-final { scan-tree-dump "sub_val ..x., 1.;" "original" } }
+! { dg-final { scan-tree-dump "sub_val .120, 1.;" "original" } }
 ! { dg-final { scan-tree-dump "subiso_val .121.;" "original" } }
-! { dg-final { scan-tree-dump "subiso2_val ..z..;" "original" } }
+! { dg-final { scan-tree-dump "subiso2_val .122.;" "original" } }
 !
-- 
2.40.1


  parent reply	other threads:[~2023-08-09 20:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-09 20:21 [PATCH 0/3] fortran: fix length one character dummy args [PR110419] Mikael Morin
2023-08-09 20:21 ` [PATCH 1/3] fortran: New predicate gfc_length_one_character_type_p Mikael Morin
2023-08-09 20:21 ` Mikael Morin [this message]
2023-08-09 20:21 ` [PATCH 3/3] testsuite: Use distinct explicit error codes in value_9.f90 Mikael Morin
2023-08-13 21:16 ` [PATCH 0/3] fortran: fix length one character dummy args [PR110419] Harald Anlauf
2023-08-14 19:47   ` Mikael Morin

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=20230809202122.695376-3-mikael@gcc.gnu.org \
    --to=mikael@gcc.gnu.org \
    --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).