Hi all,

attached patch fixes a rather old open issue, that I stumbled upon
while trying to figure, why a test failed on the command line but not
in the testsuite. The implementation of the STOP command in caf_single
did not hand the errorcode over to the OS, as does non-caf STOP and as
it is required by the standard. So I fixed that. I also added reporting
of exceptions to the coarray (ERROR)? STOP routines. For this I have
exported the existing function of the regular gfortran runtime library.
I tried to do this via iexport_proto, but was never able to access the
routine from the caf-library. I always got linker errors.

After fixing caf-STOP the testsuite reported one regression, which I
also fixed in send_by_ref.

Bootstrapped and regtests ok on x86_64-pc-linux-gnu / F41. Ok for
mainline?

Regards,
        Andre
--
Andre Vehreschild * Email: vehre ad gcc dot gnu dot org
From f6e3e34c33be7e8d8753079b9b26f9f4044ccd26 Mon Sep 17 00:00:00 2001
From: Andre Vehreschild <ve...@gcc.gnu.org>
Date: Wed, 18 Dec 2024 12:43:39 +0100
Subject: [PATCH] Fortran: Fix caf_stop_numeric and reporting exceptions from
 caf [PR57598]

Caf_stop_numeric always exited with code 0, which is wrong.  It shall
behave like regular stop.  Add reporting exceptions to caf's stop
handlers.  For this the existing library routine had to be exported.

libgfortran/ChangeLog:

	PR fortran/57598

	* caf/single.c (_gfortran_caf_stop_numeric): Report exceptions
	on stop. And fix send_by_ref.
	(_gfortran_caf_stop_str): Same.
	(_gfortran_caf_error_stop_str): Same.
	(_gfortran_caf_error_stop): Same.
	* gfortran.map: Add report_exception for export.
	* libgfortran.h (report_exception): Add to internal export.
	* runtime/stop.c (report_exception): Same.
---
 libgfortran/caf/single.c   | 19 +++++++++++++++----
 libgfortran/gfortran.map   |  1 +
 libgfortran/libgfortran.h  |  3 +++
 libgfortran/runtime/stop.c |  7 +++++--
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c
index 41da970e830..0ffbffa1d2b 100644
--- a/libgfortran/caf/single.c
+++ b/libgfortran/caf/single.c
@@ -263,13 +263,17 @@ _gfortran_caf_sync_images (int count __attribute__ ((unused)),
     *stat = 0;
 }

+extern void _gfortran_report_exception (void);

 void
 _gfortran_caf_stop_numeric(int stop_code, bool quiet)
 {
   if (!quiet)
-    fprintf (stderr, "STOP %d\n", stop_code);
-  exit (0);
+    {
+      _gfortran_report_exception ();
+      fprintf (stderr, "STOP %d\n", stop_code);
+    }
+  exit (stop_code);
 }


@@ -278,6 +282,7 @@ _gfortran_caf_stop_str(const char *string, size_t len, bool quiet)
 {
   if (!quiet)
     {
+      _gfortran_report_exception ();
       fputs ("STOP ", stderr);
       while (len--)
 	fputc (*(string++), stderr);
@@ -292,6 +297,7 @@ _gfortran_caf_error_stop_str (const char *string, size_t len, bool quiet)
 {
   if (!quiet)
     {
+      _gfortran_report_exception ();
       fputs ("ERROR STOP ", stderr);
       while (len--)
 	fputc (*(string++), stderr);
@@ -373,7 +379,10 @@ void
 _gfortran_caf_error_stop (int error, bool quiet)
 {
   if (!quiet)
-    fprintf (stderr, "ERROR STOP %d\n", error);
+    {
+      _gfortran_report_exception ();
+      fprintf (stderr, "ERROR STOP %d\n", error);
+    }
   exit (error);
 }

@@ -2131,14 +2140,16 @@ send_by_ref (caf_reference_t *ref, size_t *i, size_t *src_index,
 	      /* Assume that the rank and the dimensions fit for copying src
 		 to dst.  */
 	      GFC_DESCRIPTOR_DTYPE (dst) = GFC_DESCRIPTOR_DTYPE (src);
+	      GFC_DESCRIPTOR_SPAN (dst) = GFC_DESCRIPTOR_SPAN (src);
 	      stride_dst = 1;
+	      dst->offset = 0;
 	      for (size_t d = 0; d < src_rank; ++d)
 		{
 		  extent_dst = GFC_DIMENSION_EXTENT (src->dim[d]);
 		  GFC_DIMENSION_LBOUND (dst->dim[d]) = 1;
 		  GFC_DIMENSION_UBOUND (dst->dim[d]) = extent_dst;
 		  GFC_DIMENSION_STRIDE (dst->dim[d]) = stride_dst;
-		  dst->offset = -extent_dst;
+		  dst->offset -= stride_dst;
 		  stride_dst *= extent_dst;
 		}
 	      /* Null the data-pointer to make register_component allocate
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index f58edc52e3c..851df211eee 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1997,4 +1997,5 @@ GFORTRAN_15 {
     _gfortran_sminloc1_8_m2;
     _gfortran_sminloc1_8_m4;
     _gfortran_sminloc1_8_m8;
+    _gfortran_report_exception;
 } GFORTRAN_14;
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index aaa9222c43b..cf3dda07d3d 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -986,6 +986,9 @@ internal_proto(filename_from_unit);

 /* stop.c */

+extern void report_exception (void);
+iexport_proto (report_exception);
+
 extern _Noreturn void stop_string (const char *, size_t, bool);
 export_proto(stop_string);

diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c
index 2eefe21a9e9..3ac5beff6bb 100644
--- a/libgfortran/runtime/stop.c
+++ b/libgfortran/runtime/stop.c
@@ -38,7 +38,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    inexact - and we optionally ignore underflow, cf. thread starting at
    http://mailman.j3-fortran.org/pipermail/j3/2013-June/006452.html.  */

-static void
+extern void report_exception (void);
+iexport_proto (report_exception);
+
+void
 report_exception (void)
 {
   struct iovec iov[8];
@@ -108,7 +111,7 @@ report_exception (void)

   estr_writev (iov, iovcnt);
 }
-
+iexport (report_exception);

 /* A numeric STOP statement.  */

--
2.47.1

Reply via email to