Hi all, Crash is a misnomer on this PR [aside: People see the backtrace and assume]
This patch fixes the problem by correctly detecting the EOR condition for internal units. The previous check in read_sf_internal was wrong, relying probably on uninitialized memory as can be seen by the still open PR78881. Removing the bad hunk fixes the regression here and the new code lets dtio_26.f90 pass as expected.
Regression tested on x86_64. New test case will be added. OK for trunk? Will back port in a few days to 7. I will also have Rainer verify it fixes the problem on sparc (78881) Regards, Jerry 2017-05-15 Jerry DeLisle <jvdeli...@gcc.gnu.org> PR libgfortran/80727 * transfer.c (read_sf_internal): Remove bogus code to detect EOR. (read_block_form): For internal units, generate EOR if no more bytes left in unit and we are trying to read with ADVANCE='NO'.
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index f16d8c55..928a448f 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -272,12 +272,6 @@ read_sf_internal (st_parameter_dt *dtp, int *length) return NULL; } - if (base && *base == 0) - { - generate_error (&dtp->common, LIBERROR_EOR, NULL); - return NULL; - } - dtp->u.p.current_unit->bytes_left -= *length; if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) || @@ -470,11 +464,24 @@ read_block_form (st_parameter_dt *dtp, int *nbytes) } } - if (unlikely (dtp->u.p.current_unit->bytes_left == 0 - && !is_internal_unit(dtp))) + if (is_internal_unit(dtp)) { - hit_eof (dtp); - return NULL; + if (*nbytes > 0 && dtp->u.p.current_unit->bytes_left == 0) + { + if (dtp->u.p.advance_status == ADVANCE_NO) + { + generate_error (&dtp->common, LIBERROR_EOR, NULL); + return NULL; + } + } + } + else + { + if (unlikely (dtp->u.p.current_unit->bytes_left == 0)) + { + hit_eof (dtp); + return NULL; + } } *nbytes = dtp->u.p.current_unit->bytes_left;
! { dg-do run } ! PR80727 Crash of runtime gfortran library during integer transformation ! Note: before the patch this was giving an incorrect EOR error on READ. program gfortran_710_io_bug character str*4 integer*4 i4 str ='' i = 256 write(str,fmt='(a)') i i = 0 read ( unit=str(1:4), fmt='(a)' ) i4 if (i4.ne.256) call abort end program gfortran_710_io_bug