This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, libgfortran] [7/8 Regression] Crash of runtime gfortran library during integer transformation
- From: Jerry DeLisle <jvdelisle at charter dot net>
- To: "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 15 May 2017 13:10:43 -0700
- Subject: [patch, libgfortran] [7/8 Regression] Crash of runtime gfortran library during integer transformation
- Authentication-results: sourceware.org; auth=none
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 <jvdelisle@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