Dear all,

the attached patch fixes the issue reported by Anton Shterenlikht
(https://gcc.gnu.org/ml/fortran/2016-03/msg00037.html). The compiler
delegates the external library to manage the STOP statement in case
-fcoarray=lib is used.

Built and regtested on x86_64-pc-linux-gnu.

Ok for trunk and gcc-5-branch?
gcc/fortran/ChangeLog
2016-03-27  Alessandro Fanfarillo  <fanfarillo....@gmail.com>

        * trans-decl.c (gfc_build_builtin_function_decls):
        caf_stop_numeric and caf_stop_str definition.
        * trans-stmt.c (gfc_trans_stop): invoke external functions
        for stop and stop_str when coarrays are used.
        * trans.h: extern for new functions.

libgfortran/ChangeLog
2016-03-27  Alessandro Fanfarillo  <fanfarillo....@gmail.com>

        * caf/libcaf.h: caf_stop_numeric and caf_stop_str prototype.
        * caf/single.c: _gfortran_caf_stop_numeric and
        _gfortran_caf_stop_str implementation.

commit bb407679e918dfb9cbc769594cf39a6bd09dd9d9
Author: Alessandro Fanfarillo <fanfari...@ing.uniroma2.it>
Date:   Sun Mar 27 16:42:59 2016 +0200

    Adding caf_stop_str and caf_stop_numeric

diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 4bd7dc4..309baf1 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -137,6 +137,8 @@ tree gfor_fndecl_caf_sendget;
 tree gfor_fndecl_caf_sync_all;
 tree gfor_fndecl_caf_sync_memory;
 tree gfor_fndecl_caf_sync_images;
+tree gfor_fndecl_caf_stop_str;
+tree gfor_fndecl_caf_stop_numeric;
 tree gfor_fndecl_caf_error_stop;
 tree gfor_fndecl_caf_error_stop_str;
 tree gfor_fndecl_caf_atomic_def;
@@ -3550,6 +3552,18 @@ gfc_build_builtin_function_decls (void)
       /* CAF's ERROR STOP doesn't return.  */
       TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop_str) = 1;
 
+      gfor_fndecl_caf_stop_numeric = gfc_build_library_function_decl_with_spec 
(
+        get_identifier (PREFIX("caf_stop_numeric")), ".R.",
+        void_type_node, 1, gfc_int4_type_node);
+      /* CAF's STOP doesn't return.  */
+      TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_numeric) = 1;
+
+      gfor_fndecl_caf_stop_str = gfc_build_library_function_decl_with_spec (
+        get_identifier (PREFIX("caf_stop_str")), ".R.",
+        void_type_node, 2, pchar_type_node, gfc_int4_type_node);
+      /* CAF's STOP doesn't return.  */
+      TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1;
+
       gfor_fndecl_caf_atomic_def = gfc_build_library_function_decl_with_spec (
        get_identifier (PREFIX("caf_atomic_define")), "R..RW",
        void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index cb54499..2fc43ed 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -635,7 +635,9 @@ gfc_trans_stop (gfc_code *code, bool error_stop)
                                 ? (flag_coarray == GFC_FCOARRAY_LIB
                                    ? gfor_fndecl_caf_error_stop_str
                                    : gfor_fndecl_error_stop_string)
-                                : gfor_fndecl_stop_string,
+                                : (flag_coarray == GFC_FCOARRAY_LIB
+                                   ? gfor_fndecl_caf_stop_str
+                                   : gfor_fndecl_stop_string),
                                 2, build_int_cst (pchar_type_node, 0), tmp);
     }
   else if (code->expr1->ts.type == BT_INTEGER)
@@ -646,7 +648,9 @@ gfc_trans_stop (gfc_code *code, bool error_stop)
                                 ? (flag_coarray == GFC_FCOARRAY_LIB
                                    ? gfor_fndecl_caf_error_stop
                                    : gfor_fndecl_error_stop_numeric)
-                                : gfor_fndecl_stop_numeric_f08, 1,
+                                : (flag_coarray == GFC_FCOARRAY_LIB
+                                   ? gfor_fndecl_caf_stop_numeric
+                                   : gfor_fndecl_stop_numeric_f08), 1,
                                 fold_convert (gfc_int4_type_node, se.expr));
     }
   else
@@ -657,7 +661,9 @@ gfc_trans_stop (gfc_code *code, bool error_stop)
                                 ? (flag_coarray == GFC_FCOARRAY_LIB
                                    ? gfor_fndecl_caf_error_stop_str
                                    : gfor_fndecl_error_stop_string)
-                                : gfor_fndecl_stop_string,
+                                : (flag_coarray == GFC_FCOARRAY_LIB
+                                   ? gfor_fndecl_caf_stop_str
+                                   : gfor_fndecl_stop_string),
                                 2, se.expr, se.string_length);
     }
 
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 316ee9b..add0cea 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -762,6 +762,8 @@ extern GTY(()) tree gfor_fndecl_caf_sendget;
 extern GTY(()) tree gfor_fndecl_caf_sync_all;
 extern GTY(()) tree gfor_fndecl_caf_sync_memory;
 extern GTY(()) tree gfor_fndecl_caf_sync_images;
+extern GTY(()) tree gfor_fndecl_caf_stop_numeric;
+extern GTY(()) tree gfor_fndecl_caf_stop_str;
 extern GTY(()) tree gfor_fndecl_caf_error_stop;
 extern GTY(()) tree gfor_fndecl_caf_error_stop_str;
 extern GTY(()) tree gfor_fndecl_caf_atomic_def;
diff --git a/libgfortran/caf/libcaf.h b/libgfortran/caf/libcaf.h
index 427c8bf..01a33f9 100644
--- a/libgfortran/caf/libcaf.h
+++ b/libgfortran/caf/libcaf.h
@@ -105,6 +105,10 @@ void _gfortran_caf_sync_all (int *, char *, int);
 void _gfortran_caf_sync_memory (int *, char *, int);
 void _gfortran_caf_sync_images (int, int[], int *, char *, int);
 
+void _gfortran_caf_stop_numeric (int32_t)
+     __attribute__ ((noreturn));
+void _gfortran_caf_stop_str (const char *, int32_t)
+     __attribute__ ((noreturn));
 void _gfortran_caf_error_stop_str (const char *, int32_t)
      __attribute__ ((noreturn));
 void _gfortran_caf_error_stop (int32_t) __attribute__ ((noreturn));
diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c
index 23278dc..f726537 100644
--- a/libgfortran/caf/single.c
+++ b/libgfortran/caf/single.c
@@ -204,6 +204,23 @@ _gfortran_caf_sync_images (int count __attribute__ 
((unused)),
     *stat = 0;
 }
 
+void
+_gfortran_caf_stop_numeric(int32_t stop_code)
+{
+  fprintf (stderr, "STOP %d\n", stop_code);
+  exit (0);
+}
+
+void
+_gfortran_caf_stop_str(const char *string, int32_t len)
+{
+  fputs ("STOP ", stderr);
+  while (len--)
+    fputc (*(string++), stderr);
+  fputs ("\n", stderr);
+
+  exit (0);
+}
 
 void
 _gfortran_caf_error_stop_str (const char *string, int32_t len)

Reply via email to