[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