Blob Blame History Raw
2007-07-21  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/32678
	* io/transfer.c (formatted_transfer_scalar): Fix off by one error in
	calculation of pos and skips. Don't allow pending_spaces to go
	negative.

	PR fortran/32678
	* gfortran.dg/fmt_t_5.f90: New test.

--- libgfortran/io/transfer.c	(revision 126821)
+++ libgfortran/io/transfer.c	(revision 126823)
@@ -893,9 +893,9 @@ formatted_transfer_scalar (st_parameter_
 	case FMT_TR:
 	  consume_data_flag = 0 ;
 
-	  pos = bytes_used + f->u.n + dtp->u.p.skips;
-	  dtp->u.p.skips = f->u.n + dtp->u.p.skips;
-	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos;
+	  dtp->u.p.skips += f->u.n;
+	  pos = bytes_used + dtp->u.p.skips - 1;
+	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
 
 	  /* Writes occur just before the switch on f->format, above, so
 	     that trailing blanks are suppressed, unless we are doing a
@@ -922,8 +922,6 @@ formatted_transfer_scalar (st_parameter_
 	      if (bytes_used == 0)
 		{
 		  dtp->u.p.pending_spaces -= f->u.n;
-		  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? 0
-					    : dtp->u.p.pending_spaces;
 		  dtp->u.p.skips -= f->u.n;
 		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
 		}
@@ -945,6 +943,8 @@ formatted_transfer_scalar (st_parameter_
 	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
 				    + pos - dtp->u.p.max_pos;
+	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
+				    ? 0 : dtp->u.p.pending_spaces;
 
 	  if (dtp->u.p.skips == 0)
 	    break;
--- gcc/testsuite/gfortran.dg/fmt_t_5.f90	(revision 126821)
+++ gcc/testsuite/gfortran.dg/fmt_t_5.f90	(revision 126823)
@@ -0,0 +1,17 @@
+! { dg-do run }
+! PR32678 GFortan works incorrectly when writing with FORMAT Tx
+! Before patch, NULLs were inserted in output.
+! Test case from reporter enhanced to detect this problem.
+      character(25) :: output
+      character(1)  :: c
+      output = ""
+      open (unit=10, file="pr32678testfile", status="replace")
+      write (10,10) '12','a','b'
+      close (10, status="keep")
+      open (unit=10, file="pr32678testfile")
+      read(10,20) output(1:21)
+      if (output(1:21).ne."ab                  x") call abort
+      close (10, status="delete")
+ 10   format (a2,t1,a1,t2,a1,t20,' x')
+ 20   format (a21)
+      end