[gfortran] add SIGNAL and ALARM intrinsics

Steve Kargl sgk@troutmask.apl.washington.edu
Fri Oct 14 02:35:00 GMT 2005


On Tue, Oct 04, 2005 at 09:58:36AM +0200, FX Coudert wrote:
> :ADDPATCH fortran:
> 
> Attached patch adds the SIGNAL and ALARM intrinsics to gfortran, that 
> were available in g77 and all commercial compilers (and used in lots of 
> scientific code, for handling "out of allocated CPU time" signals).
> 
> Built, tested and regtested on i686-linux.
> 
> OK for mainline and 4.0?
> 

FX, It looks like you confused g77 the intrinsic function and 
intrinsic subroutine for SIGNAL.  The subroutine takes an
optional integer STATUS variable; while intrinsic function
returns the status.  The g77 info file shows:

8.11.9.228 Signal Intrinsic (subroutine)

     CALL Signal(NUMBER, HANDLER, STATUS)

NUMBER: `INTEGER'; scalar; INTENT(IN).

HANDLER: Signal handler (`INTEGER FUNCTION' or `SUBROUTINE') or
dummy/global `INTEGER(KIND=1)' scalar.

STATUS: `INTEGER(KIND=7)'; OPTIONAL; scalar; INTENT(OUT).


10.5.2.128 Signal Intrinsic (function)

     Signal(NUMBER, HANDLER)

Signal: `INTEGER(KIND=7)' function.

NUMBER: `INTEGER'; scalar; INTENT(IN).

HANDLER: Signal handler (`INTEGER FUNCTION' or `SUBROUTINE') or
dummy/global `INTEGER(KIND=1)' scalar.

See getcwd.c for a method for implementing the function in terms
of the subroutine infrastructure.  I think your implementation
for ALARM is okay with one possible fix (see below), but I
haven't tested yet.

Here are some additional comments on the patch.

Index: gcc/fortran/check.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/check.c,v
retrieving revision 1.34
diff -u -3 -p -r1.34 check.c
--- gcc/fortran/check.c	17 Sep 2005 18:57:59 -0000	1.34
+++ gcc/fortran/check.c	4 Oct 2005 07:50:33 -0000
@@ -2391,6 +2391,38 @@ gfc_check_irand (gfc_expr * x)
   return SUCCESS;
 }
 
+
+try
+gfc_check_alarm_sub (gfc_expr * seconds, gfc_expr * handler, gfc_expr * status)
+{
+  if (scalar_check (seconds, 0) == FAILURE)
+    return FAILURE;
+
+  if (type_check (seconds, 0, BT_INTEGER) == FAILURE)
+    return FAILURE;
+
+  if (handler->ts.type != BT_INTEGER && handler->ts.type != BT_PROCEDURE)
+    {
+      must_be (handler, 1, "INTEGER or PROCEDURE");
+      return FAILURE;
+    }
+
+  if (handler->ts.type != BT_INTEGER && scalar_check (handler, 1) == FAILURE)
+    return FAILURE;

Is this correct?  Don't you want to call scalar_check only if 
handler->ts.type == BT_INTEGER.

 try
+gfc_check_signal_sub (gfc_expr * number, gfc_expr * handler)
+{

This is missing the "gfc_expr * status".  You can copy it from
gfc_check_alarm_sub.

+  if (handler->ts.type != BT_INTEGER && scalar_check (handler, 1) == FAILURE)
+    return FAILURE;

Same comment as above.

Index: gcc/fortran/intrinsic.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/intrinsic.c,v
retrieving revision 1.55
diff -u -3 -p -r1.55 intrinsic.c
--- gcc/fortran/intrinsic.c	22 Sep 2005 19:00:22 -0000	1.55
+++ gcc/fortran/intrinsic.c	4 Oct 2005 07:50:33 -0000
 
@@ -2260,6 +2266,10 @@ add_subroutines (void)
 	      name, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED,
 	      st, BT_INTEGER, di, OPTIONAL);
 
+  add_sym_2s ("signal", 0, 1, BT_UNKNOWN, 0, GFC_STD_GNU,
+	      gfc_check_signal_sub, NULL, gfc_resolve_signal_sub,
+	      num, BT_INTEGER, di, REQUIRED, han, BT_UNKNOWN, 0, REQUIRED);
+

This should be add_sym_3s and an optional status argument added.

Index: gcc/fortran/intrinsic.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/intrinsic.h,v
retrieving revision 1.33
diff -u -3 -p -r1.33 intrinsic.h
--- gcc/fortran/intrinsic.h	22 Sep 2005 19:00:23 -0000	1.33
+++ gcc/fortran/intrinsic.h	4 Oct 2005 07:50:33 -0000
@@ -146,6 +147,7 @@ try gfc_check_perror (gfc_expr *);
 try gfc_check_rename_sub (gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_link_sub (gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_symlnk_sub (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_signal_sub (gfc_expr *, gfc_expr *);

Need an additional gfc_expr *.

Index: gcc/fortran/iresolve.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/iresolve.c,v
retrieving revision 1.41
diff -u -3 -p -r1.41 iresolve.c
--- gcc/fortran/iresolve.c	3 Oct 2005 07:22:18 -0000	1.41
+++ gcc/fortran/iresolve.c	4 Oct 2005 07:50:33 -0000
@@ -1649,6 +1649,44 @@ gfc_resolve_verify (gfc_expr * f, gfc_ex
 /* Intrinsic subroutine resolution.  */
 
+void
+gfc_resolve_signal_sub (gfc_code * c)
+{
+  const char *name;
+  gfc_expr *number, *handler;

Copy your status code from gfc_resolve_alarm_sub.

Index: libgfortran/intrinsics/signal.c
===================================================================
RCS file: libgfortran/intrinsics/signal.c
diff -N libgfortran/intrinsics/signal.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgfortran/intrinsics/signal.c	4 Oct 2005 07:50:34 -0000
+
+/* SIGNAL intrinsic with PROCEDURE as handler  */
+extern void signal_i4 (GFC_INTEGER_4 *, void *);
+iexport_proto(signal_i4);
+
+void
+signal_i4 (GFC_INTEGER_4 *number, void *handler)

You'll need to adapt this for GFC_INTEGER_4 *status.
Likewise, for the other signal functions.

-- 
Steve



More information about the Fortran mailing list