Hi all,
The problem here is that we never set the err return to LIBERROR_END in all
cases. For the example case we are detecting the EOF condition inside the
read_integer procedure and it gets acted on correctly at higher levels in the
code. Consequently in the big loop over the array where we call
list_formatted_read_scalar, we never returned an error code so we never exited
the loop early.
The patch tests for the EOF first locally as before, but then returns the error
flags set in dtp->common.flags which are set globally in the individual read
procedures whene hit_eof is called.
Regression tested on x86_64. I have added a test case which will check the
execution time of the loop. The previous results of the REAd were correct, just
took a long time on large arrays.
OK for trunk?
Regards,
Jerry
2017-05-28 Jerry DeLisle <jvdeli...@gcc.gnu.org>
PR libgfortran/35339
* list_read.c.c (list_formatted_read_scala): Set the err return
value to the common.flags error values.
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 6c00d11b..b6cd6670 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -2298,11 +2298,16 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
free_saved (dtp);
cleanup:
+ /* err may have been set above from finish_separator, so if it is set
+ trigger the hit_eof. The hit_eof will set bits in common.flags. */
if (err == LIBERROR_END)
{
free_line (dtp);
hit_eof (dtp);
}
+ /* Now we check common.flags for any errors that could have occurred in
+ a READ elsewhere such as in read_integer. */
+ err = dtp->common.flags & IOPARM_LIBRETURN_MASK;
fbuf_flush_list (dtp->u.p.current_unit, LIST_READING);
return err;
}
! { dg-do run }
! PR35339 Missed optimization, this test case took several seconds to
program internalread
implicit none
integer m
parameter(m=1000000)
character value*10
character(80) :: result
integer i,j,intvalues(m)
real :: start, finish
intvalues = 33
call cpu_time(start)
do j=1,100
write(value,'(i3,a5)') j," 5 69"
read(value,*,end=20) intvalues
20 write(result,*) (intvalues(i),i=2,4)
if (result.ne.(' 5 69 33')) call abort
call cpu_time(finish)
if ((finish-start).gt. 2.0) call abort
enddo
end program internalread