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]

[patch, libgfortran] PR31099 [4.3/4.2 regression] Runtime error on legal code using RECL


:ADDPATCH fortran:

Hi,

This patch fixes the problem by doing two things:

First, it properly initializes the bytes_left and recl_subrecord in st_open and updates these properly in next_record_r and next_record_w.

Second, fixes the test for exceeding the current record length. This resolves the incorrect error for reads when RECL is specified. If you look at the original code, you will see that no matter what, if RECL was specified, an error would be issued.

I think one of the contributing factors is that setting the bytes_left correctly in gfortran 4.1 relied on falling through in the switch case in next_record, so it was set farther down.

Regression tested on x86-64-Linux. I would suggest we get this into 4.2 immediately as well as 4.3 I will clean up and dejagnuize the test case while this is being reviewed.

Awaiting approval.

Regards,

Jerry

2007-03-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/31099
	* io/open.c (new_unit): Initialize bytes_left and recl_subrecord.
	* io/transfer.c (next_record_w): Set bytes left to record length for
	sequential unformatted I/O.
	(next_record_r): Ditto.
	(read_block_direct): Fix test for exceeding bytes_left.
Index: open.c
===================================================================
--- open.c	(revision 122529)
+++ open.c	(working copy)
@@ -437,6 +437,8 @@ new_unit (st_parameter_open *opp, gfc_un
     {
       u->flags.has_recl = 1;
       u->recl = opp->recl_in;
+      u->recl_subrecord = u->recl;
+      u->bytes_left = u->recl;
     }
   else
     {
Index: transfer.c
===================================================================
--- transfer.c	(revision 122529)
+++ transfer.c	(working copy)
@@ -434,11 +434,10 @@ read_block_direct (st_parameter_dt *dtp,
 
   /* Check whether we exceed the total record length.  */
 
-  if (dtp->u.p.current_unit->flags.has_recl)
+  if (dtp->u.p.current_unit->flags.has_recl
+      && (*nbytes > (size_t) dtp->u.p.current_unit->bytes_left))
     {
-      to_read_record =
-	*nbytes > (size_t) dtp->u.p.current_unit->bytes_left ?
-	*nbytes : (size_t) dtp->u.p.current_unit->bytes_left;
+      to_read_record = (size_t) dtp->u.p.current_unit->bytes_left;
       short_record = 1;
     }
   else
@@ -2152,6 +2151,7 @@ next_record_r (st_parameter_dt *dtp)
     
     case UNFORMATTED_SEQUENTIAL:
       next_record_r_unf (dtp, 1);
+      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
       break;
 
     case FORMATTED_DIRECT:
@@ -2377,6 +2377,7 @@ next_record_w (st_parameter_dt *dtp, int
 
     case UNFORMATTED_SEQUENTIAL:
       next_record_w_unf (dtp, 0);
+      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
       break;
 
     case FORMATTED_STREAM:
  PROGRAM TEST
    INTEGER :: A, B
    a=1
    b=2
    OPEN(10, FORM="UNFORMATTED", RECL=8)
    WRITE(10) A,B
    write(10) A,B
    write(10) A,B
    WRITE(10) B,A
    rewind(10)
    B=0
    A=0
    read(10) A, B
    print *, A, B
  END PROGRAM TEST


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