This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix Fortran FMT_T handling
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Fri, 2 Sep 2005 13:44:47 -0400
- Subject: [PATCH] Fix Fortran FMT_T handling
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcase (origin from
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=166480
testcase) fails to read the numbers correctly. The problem is that on the
second line when skipping characters formatted_transfer overwrites
FMT_T's f->u.n (i.e. position to which chars should be skipped) with
skips (the number of chars that it wants to be skipped yb read_x routine).
But this means that from that point on the original f->u.n value is lost
and on the next (3rd) line it will work as t6 rather than the requested t7.
As read_x is an internal function, I think it should be ok to change it's
argument. If not, alternatively f->u.n could be saved into a local
variable, overwritten and after read_x returns restored.
Ok for HEAD/4.0?
2005-09-02 Jakub Jelinek <jakub@redhat.com>
* io/read.c (read_x): Take int argument instead of fnode * and
digging the N from F->u.n.
* io/io.h (read_x): Adjust prototype.
* io/transfer.c (formatted_transfer): Adjust callers. Don't clobber
f->u.n for FMT_T.
* gfortran.dg/fmt_t_1.f90: New test.
--- libgfortran/io/io.h.jj 2005-08-29 10:25:04.000000000 +0200
+++ libgfortran/io/io.h 2005-09-02 19:20:31.000000000 +0200
@@ -589,7 +589,7 @@ internal_proto(read_f);
extern void read_l (fnode *, char *, int);
internal_proto(read_l);
-extern void read_x (fnode *);
+extern void read_x (int);
internal_proto(read_x);
extern void read_radix (fnode *, char *, int, int);
--- libgfortran/io/transfer.c.jj 2005-08-27 10:13:09.000000000 +0200
+++ libgfortran/io/transfer.c 2005-09-02 19:20:47.000000000 +0200
@@ -705,7 +705,7 @@ formatted_transfer (bt type, void *p, in
/* Writes occur just before the switch on f->format, above, so that
trailing blanks are suppressed. */
if (g.mode == READING)
- read_x (f);
+ read_x (f->u.n);
break;
@@ -736,10 +736,7 @@ formatted_transfer (bt type, void *p, in
if (g.mode == READING)
{
if (skips > 0)
- {
- f->u.n = skips;
- read_x (f);
- }
+ read_x (skips);
if (skips < 0)
{
move_pos_offset (current_unit->s, skips);
--- libgfortran/io/read.c.jj 2005-09-02 09:01:45.000000000 +0200
+++ libgfortran/io/read.c 2005-09-02 19:20:44.000000000 +0200
@@ -831,12 +831,8 @@ read_f (fnode * f, char *dest, int lengt
* and never look at it. */
void
-read_x (fnode * f)
+read_x (int n)
{
- int n;
-
- n = f->u.n;
-
if ((current_unit->flags.pad == PAD_NO || is_internal_unit ())
&& current_unit->bytes_left < n)
n = current_unit->bytes_left;
--- gcc/testsuite/gfortran.dg/fmt_t_1.f90.jj 2005-09-02 19:20:04.000000000 +0200
+++ gcc/testsuite/gfortran.dg/fmt_t_1.f90 2005-09-02 19:34:42.000000000 +0200
@@ -0,0 +1,14 @@
+! { dg-do run }
+ integer nin, nrow, vec(15)
+ nin = 1
+ open (unit = nin)
+ write (nin, fmt='(a)') '001 1 2 3 4 5 6'
+ write (nin, fmt='(a)') '000000 7 8 9101112'
+ write (nin, fmt='(a)') '000000131415'
+ close (nin)
+ open (unit = nin)
+ read (nin, fmt='(i6, (t7, 6i2))') nrow, (vec(i), i=1,15)
+ close (nin)
+ if (nrow.ne.1) call abort
+ if (any (vec.ne.(/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15/))) call abort
+ end
Jakub