[part2,committed] Fortran: ABI for scalar CHARACTER(LEN=1),VALUE dummy argument [PR110360]

Message ID trinity-b942f382-e8c1-4447-a562-0567f1f1f923-1687633555558@3c-app-gmx-bap37
State Unresolved
Headers
Series [part2,committed] Fortran: ABI for scalar CHARACTER(LEN=1),VALUE dummy argument [PR110360] |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Harald Anlauf June 24, 2023, 7:05 p.m. UTC
  Dear all,

the first part of the patch came with a testcase that also exercised
code for constant string arguments, which was not touched by that patch
but seems to have caused runtime failures on big-endian platforms
(e.g. Power-* BE) for all optimization levels, and on x86 / -m32
at -O1 and higher (not at -O0).

I did not see any issues on x86 / -m64 and any optimization level,
but could reproduce a problem with x86 / -m32 at -O1, which appears
to be related how arguments that are to be passed by value are
handled when there is a mismatch between the function prototype
and the passed argument.  The solution is to truncate too long
constant string arguments, fixed by the attached patch, pushed as:

https://gcc.gnu.org/g:3f97d10aa1ff5984d6fd657f246d3f251b254ff1

and see attached.

* * *

I found gcc-testresults quite helpful in checking whether my patch
caused trouble on architectures different from the one I'm working
on.  The value (pun intended) would have been even greater if
output of runtime failures would also be made available.
Many (Fortran) tests provide either a stop code, or some hopefully
helpful diagnostic output on stdout intended for locating errors
on platforms where one has no direct access to, or is less
familiar with.  Far better than a plain

FAIL: gfortran.dg/value_9.f90   -O1  execution test

* * *

Thanks,
Harald
  

Patch

From 3f97d10aa1ff5984d6fd657f246d3f251b254ff1 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Sat, 24 Jun 2023 20:36:53 +0200
Subject: [PATCH] Fortran: ABI for scalar CHARACTER(LEN=1),VALUE dummy argument
 [PR110360]

gcc/fortran/ChangeLog:

	PR fortran/110360
	* trans-expr.cc (gfc_conv_procedure_call): Truncate constant string
	argument of length > 1 passed to scalar CHARACTER(1),VALUE dummy.
---
 gcc/fortran/trans-expr.cc | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index c92fccd0be2..63e3cf9681e 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6395,20 +6395,25 @@  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.
-		       The BIND(C) case is handled elsewhere.
-		       TODO: truncate constant strings to length 1.  */
+		       Constant strings are truncated to length 1.
+		       The BIND(C) case is handled elsewhere.  */
 		    if (fsym->ts.type == BT_CHARACTER
 			&& !fsym->ts.is_c_interop
 			&& fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT
 			&& fsym->ts.u.cl->length->ts.type == BT_INTEGER
 			&& (mpz_cmp_ui
-			    (fsym->ts.u.cl->length->value.integer, 1) == 0)
-			&& e->expr_type != EXPR_CONSTANT)
+			    (fsym->ts.u.cl->length->value.integer, 1) == 0))
 		      {
-			parmse.expr = gfc_string_to_single_character
-			  (build_int_cst (gfc_charlen_type_node, 1),
-			   parmse.expr,
-			   e->ts.kind);
+			if (e->expr_type != EXPR_CONSTANT)
+			  parmse.expr = gfc_string_to_single_character
+			    (build_int_cst (gfc_charlen_type_node, 1),
+			     parmse.expr,
+			     e->ts.kind);
+			else if (e->value.character.length > 1)
+			  {
+			    e->value.character.length = 1;
+			    gfc_conv_expr (&parmse, e);
+			  }
 		      }

 		    if (fsym->attr.optional
--
2.35.3