This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, libgfortran] PR31099 [4.3/4.2 regression] Runtime error on legal code using RECL
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: Fortran List <fortran at gcc dot gnu dot org>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 09 Mar 2007 13:24:26 -0800
- Subject: [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