This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR30947 - resolving ALARM


Hi all.

I spent this evening feeling my way around iresolve.c and trans-intrinsic.c to 
figure out how to fix the code that is generated for ALARM. It happens, that 
the intent(out) value of the STATUS argument is lost:

[snip]
  static int1 h = 9;
  static int1 stat = -1;
  static int1 sec = 1;

  _gfortran_set_std (70, 127, 0, 0);
  {
    int4 D.1005;
    int4 D.1004;
    int4 D.1003;

    D.1003 = (int4) sec;
    D.1004 = (int4) h;
    D.1005 = (int4) stat;
    _gfortran_alarm_sub_int (&D.1003, &D.1004, &D.1005);
  }
[snip]

The first attempt was to find a way to add a line as 
    stat = (int1) D.1005;
which would solve the issue ...

OTOH, I learned that there are two schools in the overall list of intrinsics: 
gfc_convert_type everything or not at all. For example, the bessel family 
take their arguments "as is", without any casting prior to calling the 
builtin functions. 

Thus, removing any casts from iresolve.c(gfc_resolve_alarm_sub) results in 
this code:

[snip]
  static int4 h = 1;
  static int1 sec = 2;
  static int2 stat = -1;

  _gfortran_set_std (68, 127, 0);
  _gfortran_alarm_sub_int (&sec, &h, &stat);
[snip]

This seems to work with any (integer) input type for sec and stat. The 
question is whether this solution is acceptable? 


gcc/fortran/
2007-03-07  Daniel Franke  <franke.daniel@gmail.com>

	PR fortran/30947
	* iresolve.c (gfc_resolve_alarm_sub): Do not convert integer types.
	* gfortran.h (gfc_generic_isym_id): Added GFC_ISYM_ALARM.
	* trans-intrinsic.c (gfc_conv_intrinsic_function): Likewise.
	* intrinsic.texi (ALARM): Improve documentation.

libgfortran/
2007-03-07  Daniel Franke  <franke.daniel@gmail.com>

	PR fortran/30947
	* intrinsics/signal.c (alarm_sub_int): Derefence pointer to handler 
	before casting.

Currently bootstrapping and testing on i686-pc-linux-gnu.

Ok for trunk and 4.2 if tests are successfull?

Regards
	Daniel
Index: gcc/fortran/iresolve.c
===================================================================
--- gcc/fortran/iresolve.c	(revision 122639)
+++ gcc/fortran/iresolve.c	(working copy)
@@ -2376,19 +2376,10 @@
 
   /* handler can be either BT_INTEGER or BT_PROCEDURE  */
   if (handler->ts.type == BT_INTEGER)
-    {
-      if (handler->ts.kind != gfc_c_int_kind)
-	gfc_convert_type (handler, &ts, 2);
-      name = gfc_get_string (PREFIX ("alarm_sub_int"));
-    }
+    name = gfc_get_string (PREFIX ("alarm_sub_int"));
   else
     name = gfc_get_string (PREFIX ("alarm_sub"));
 
-  if (seconds->ts.kind != gfc_c_int_kind)
-    gfc_convert_type (seconds, &ts, 2);
-  if (status != NULL && status->ts.kind != gfc_c_int_kind)
-    gfc_convert_type (status, &ts, 2);
-
   c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
 }
 
Index: gcc/fortran/intrinsic.texi
===================================================================
--- gcc/fortran/intrinsic.texi	(revision 122640)
+++ gcc/fortran/intrinsic.texi	(working copy)
@@ -782,12 +782,16 @@
 @table @asis
 @item @emph{Description}:
 @code{ALARM(SECONDS, HANDLER [, STATUS])} causes external subroutine @var{HANDLER}
-to be executed after a delay of @var{SECONDS} by using @code{alarm(1)} to
+to be executed after a delay of @var{SECONDS} by using @code{alarm(2)} to
 set up a signal and @code{signal(2)} to catch it. If @var{STATUS} is
 supplied, it will be returned with the number of seconds remaining until
 any previously scheduled alarm was due to be delivered, or zero if there
 was no previously scheduled alarm.
 
+The @code{HANDLER} may either a @code{SUBROUTINE}, a @code{INTEGER FUNCTION} or
+an @code{INTEGER} scalar. The scalar values may be either @code{SIG_IGN=1} to
+ignore the alarm generated or @code{SIG_DFL=0} to set the default action.
+
 @item @emph{Standard}:
 GNU extension
 
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 122639)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -314,6 +314,7 @@
   GFC_ISYM_ADJUSTR,
   GFC_ISYM_AIMAG,
   GFC_ISYM_AINT,
+  GFC_ISYM_ALARM,
   GFC_ISYM_ALL,
   GFC_ISYM_ALLOCATED,
   GFC_ISYM_ANINT,
Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c	(revision 122639)
+++ gcc/fortran/trans-intrinsic.c	(working copy)
@@ -3837,6 +3837,7 @@
       break;
 
     case GFC_ISYM_ACCESS:
+    case GFC_ISYM_ALARM:
     case GFC_ISYM_CHDIR:
     case GFC_ISYM_CHMOD:
     case GFC_ISYM_ETIME:
Index: libgfortran/intrinsics/signal.c
===================================================================
--- libgfortran/intrinsics/signal.c	(revision 122639)
+++ libgfortran/intrinsics/signal.c	(working copy)
@@ -170,14 +170,14 @@
 #if defined (SIGALRM) && defined (HAVE_ALARM) && defined (HAVE_SIGNAL)
   if (status != NULL)
     {
-      if (signal (SIGALRM, (void (*)(int)) handler) == SIG_ERR)
+      if (signal (SIGALRM, (void (*)(int)) *handler) == SIG_ERR)
 	*status = -1;
       else
 	*status = alarm (*seconds);
     }
   else
     {
-      signal (SIGALRM, (void (*)(int)) handler);
+      signal (SIGALRM, (void (*)(int)) *handler);
       alarm (*seconds);
     }
 #else

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]