The error condition isn't detected for write, and is mis-represented as an EOF for read. $ cat exceed-recl-direct.f program main integer i,j open (10, form="unformatted", access="direct", recl=4) write (10, rec=1, err=10) 1,2 print *,"did not detect error on write" 10 continue read (10, rec=1, err=20) i, j print *,"did not detect error on read" 20 continue end $ g77 exceed-recl-direct.f $ ./a.out $ gfortran exceed-recl-direct.f $ ./a.out did not detect error on write At line 7 of file exceed-recl-direct.f Fortran runtime error: End of file Different codepath from PR 30009, nevertheless related.
I forgot to assign this to myself. I'll do this together with PR 30009.
Subject: Bug 30056 Author: tkoenig Date: Wed Dec 6 19:25:44 2006 New Revision: 119592 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=119592 Log: 2006-12-06 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/30009 PR libfortran/30056 * gfortran.dg/read_eof_4.f90: Add tests. * gfortran.dg/readwrite_unf_direct_eor_1.f90: New test. * gfortran.dg/unf_read_corrupted_1.f90: New test. 2006-12-06 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/30009 PR libfortran/30056 * libgfortran.h: Add ERROR_CORRUPT_FILE to error_codes. * runtime/error.c (translate_error): Add handling for ERROR_CORRUPT_FILE. * io/transfer.c (read_block_direct): Add comment about EOR for stream files. Remove test for no bytes left for direct access files. Generate an ERROR_SHORT_RECORD if the read was short. For unformatted sequential files: Check endfile condition. Remove test for no bytes left. End of file here means that the file structure has been corrupted. Pre-position the file for the next record in case of error. (write_buf): Whitespace fix. Subtract the number of bytes written from bytes_left. Added: trunk/gcc/testsuite/gfortran.dg/readwrite_unf_direct_eor_1.f90 trunk/gcc/testsuite/gfortran.dg/unf_read_corrupted_1.f90 Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/read_eof_4.f90 trunk/libgfortran/ChangeLog trunk/libgfortran/io/transfer.c trunk/libgfortran/libgfortran.h trunk/libgfortran/runtime/error.c
Subject: Bug 30056 Author: tkoenig Date: Sun Dec 10 22:16:14 2006 New Revision: 119712 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=119712 Log: 2006-12-10 Thomas Koenig <Thomas.Koenig@online.de> Backport from mainline PR libfortran/29568 * gfortran.dg/convert_implied_open.f90: Change to new default record length. * gfortran.dg/unf_short_record_1.f90: Adapt to new error message. * gfortran.dg/unformatted_subrecords_1.f90: New test. PR libfortran/30009 PR libfortran/30056 * gfortran.dg/read_eof_4.f90: Add tests. * gfortran.dg/readwrite_unf_direct_eor_1.f90: New test. * gfortran.dg/unf_read_corrupted_1.f90: New test. 2006-12-10 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/29568 * gfortran.h (gfc_option_t): Add max_subrecord_length. (top level): Define MAX_SUBRECORD_LENGTH. * lang.opt: Add option -fmax-subrecord-length=. * trans-decl.c: Add new function set_max_subrecord_length. (gfc_generate_function_code): If we are within the main program and max_subrecord_length has been set, call set_max_subrecord_length. * options.c (gfc_init_options): Add defaults for max_subrecord_lenght, convert and record_marker. (gfc_handle_option): Add handling for -fmax_subrecord_length. * invoke.texi: Document the new default for -frecord-marker=<n>. 2006-12-10 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/29568 * libgfortran/libgfortran.h (compile_options_t): Add record_marker. (top level): Define GFC_MAX_SUBRECORD_LENGTH. * runtime/compile_options.c (set_record_marker): Change default to four-byte record marker. (set_max_subrecord_length): New function. * runtime/error.c (translate_error): Change error message for short record on unformatted read. * io/io.h (gfc_unit): Add recl_subrecord, bytes_left_subrecord and continued. * io/file_pos.c (unformatted_backspace): Change default of record marker size to four bytes. Loop over subrecords. * io/open.c: Default recl is max_offset. If compile_options.max_subrecord_length has been set, set set u->recl_subrecord to its value, to the maximum value otherwise. * io/transfer.c (top level): Add prototypes for us_read, us_write, next_record_r_unf and next_record_w_unf. (read_block_direct): Separate codepaths for unformatted direct and unformatted sequential. If a recl has been set by the user, use the number of bytes left for the record if it is smaller than the read request. Loop over subrecords. Set an error if the user has set a recl and the read was short. (write_buf): Separate codepaths for unformatted direct and unformatted sequential. If a recl has been set by the user, use the number of bytes left for the record if it is smaller than the read request. Loop over subrecords. Set an error if the user has set a recl and the read was short. (us_read): Add parameter continued (to indicate that bytes_left should not be intialized). Change default of record marker size to four bytes. Use subrecord. If the subrecord length is smaller than zero, this indicates a continuation. (us_write): Add parameter continued (to indicate that the continued flag should be set). Use subrecord. (pre_position): Use 0 for continued on us_write and us_read calls. (skip_record): New function. (next_record_r_unf): New function. (next_record_r): Use next_record_r_unf. (write_us_marker): Default size for record markers is four bytes. (next_record_w_unf): New function. (next_record_w): Use next_record_w_unf. PR libfortran/30009 PR libfortran/30056 * libgfortran.h: Add ERROR_CORRUPT_FILE to error_codes. * runtime/error.c (translate_error): Add handling for ERROR_CORRUPT_FILE. * io/transfer.c (read_block_direct): Add comment about EOR for stream files. Remove test for no bytes left for direct access files. Generate an ERROR_SHORT_RECORD if the read was short. For unformatted sequential files: Check endfile condition. Remove test for no bytes left. End of file here means that the file structure has been corrupted. Pre-position the file for the next record in case of error. (write_buf): Whitespace fix. Subtract the number of bytes written from bytes_left. Added: branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/readwrite_unf_direct_eor_1.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/unf_read_corrupted_1.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/unformatted_subrecord_1.f90 Modified: branches/gcc-4_2-branch/gcc/fortran/ChangeLog branches/gcc-4_2-branch/gcc/fortran/gfortran.h branches/gcc-4_2-branch/gcc/fortran/lang.opt branches/gcc-4_2-branch/gcc/fortran/options.c branches/gcc-4_2-branch/gcc/fortran/trans-decl.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/convert_implied_open.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/read_eof_4.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/unf_short_record_1.f90 branches/gcc-4_2-branch/libgfortran/ChangeLog branches/gcc-4_2-branch/libgfortran/io/file_pos.c branches/gcc-4_2-branch/libgfortran/io/io.h branches/gcc-4_2-branch/libgfortran/io/open.c branches/gcc-4_2-branch/libgfortran/io/transfer.c branches/gcc-4_2-branch/libgfortran/libgfortran.h branches/gcc-4_2-branch/libgfortran/runtime/compile_options.c branches/gcc-4_2-branch/libgfortran/runtime/error.c
As discussed on PR 30009, this is to costly to fix for 4.1 and risks breaking things. I'm unassigning myself in case anybody wants to tackle it.
No need to backport this further.