diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-11-22 09:10:41 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-11-22 09:10:41 +0100 |
commit | e14568432a5df8754c845e247935fcbabd97612e (patch) | |
tree | fd3f39fc5493d036706217573269adc0cd79d272 /libgfortran | |
parent | 220904438f2970c4187280d3088e3c4e1017f069 (diff) | |
download | gcc-e14568432a5df8754c845e247935fcbabd97612e.zip gcc-e14568432a5df8754c845e247935fcbabd97612e.tar.gz gcc-e14568432a5df8754c845e247935fcbabd97612e.tar.bz2 |
re PR libfortran/37839 (st_parameter_dt has unwanted padding, is out of sync with compiler)
PR libfortran/37839
* trans-io.c (gfc_build_io_library_fndecls): Decrease pad size back
to 16 pointers plus 32 integers. Don't use max integer kind
alignment, only gfc_intio_kind's alignment.
(gfc_trans_inquire): Only set flags2 if mask2 is non-zero.
* ioparm.def: Fix order, bitmasks and types of inquire round, sign
and pending fields. Move u in dt before id.
* io.c (gfc_free_inquire): Free decimal and size exprs.
(match_inquire_element): Match size instead of matching blank twice.
(gfc_resolve_inquire): Resolve size.
* gfortran.dg/f2003_inquire_1.f03: New test.
* gfortran.dg/f2003_io_1.f03: Remove xfail.
* gfortran.dg/f2003_io_4.f03: Likewise.
* gfortran.dg/f2003_io_5.f03: Likewise.
* gfortran.dg/f2003_io_6.f03: Likewise.
* gfortran.dg/f2003_io_7.f03: Likewise.
* io/io.h (IOPARM_INQUIRE_HAS_ROUND, IOPARM_INQUIRE_HAS_SIGN,
IOPARM_INQUIRE_HAS_PENDING): Adjust values.
(st_parameter_inquire): Reorder and fix types of round, sign and
pending fields.
(st_parameter_43, st_parameter_44): Removed.
(st_parameter_dt): Put back struct definition directly to u.p
declaration. Change type of u.p.size_used from gfc_offset to
GFC_IO_INT. Decrease back size of u.pad to 16 pointers and
32 ints. Put id, pos, asynchronous, blank, decimal, delim,
pad, round and sign fields after the union.
* io/inquire.c (inquire_via_unit, inquire_via_filename): Only read
flags2 if it is defined.
* io/transfer.c (read_sf, read_block_form, write_block): Cast
additions to size_used to GFC_IO_INT instead of gfc_offset.
(data_transfer_init): Clear whole u.p struct. Adjust
for moving id, pos, asynchronous, blank, decimal, delim, pad,
round and sign fields from u.p directly into st_parameter_dt.
(finalize_transfer): Don't cast size_used to GFC_IO_INT.
* io/file_pos.c (st_endfile): Clear whole u.p struct.
From-SVN: r142111
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 23 | ||||
-rw-r--r-- | libgfortran/io/file_pos.c | 2 | ||||
-rw-r--r-- | libgfortran/io/inquire.c | 6 | ||||
-rw-r--r-- | libgfortran/io/io.h | 268 | ||||
-rw-r--r-- | libgfortran/io/transfer.c | 24 |
5 files changed, 131 insertions, 192 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 56fff3f..f2d279d 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,26 @@ +2008-11-22 Jakub Jelinek <jakub@redhat.com> + + PR libfortran/37839 + * io/io.h (IOPARM_INQUIRE_HAS_ROUND, IOPARM_INQUIRE_HAS_SIGN, + IOPARM_INQUIRE_HAS_PENDING): Adjust values. + (st_parameter_inquire): Reorder and fix types of round, sign and + pending fields. + (st_parameter_43, st_parameter_44): Removed. + (st_parameter_dt): Put back struct definition directly to u.p + declaration. Change type of u.p.size_used from gfc_offset to + GFC_IO_INT. Decrease back size of u.pad to 16 pointers and + 32 ints. Put id, pos, asynchronous, blank, decimal, delim, + pad, round and sign fields after the union. + * io/inquire.c (inquire_via_unit, inquire_via_filename): Only read + flags2 if it is defined. + * io/transfer.c (read_sf, read_block_form, write_block): Cast + additions to size_used to GFC_IO_INT instead of gfc_offset. + (data_transfer_init): Clear whole u.p struct. Adjust + for moving id, pos, asynchronous, blank, decimal, delim, pad, + round and sign fields from u.p directly into st_parameter_dt. + (finalize_transfer): Don't cast size_used to GFC_IO_INT. + * io/file_pos.c (st_endfile): Clear whole u.p struct. + 2008-11-20 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/37472 diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c index 25b0108..4054b3a 100644 --- a/libgfortran/io/file_pos.c +++ b/libgfortran/io/file_pos.c @@ -300,7 +300,7 @@ st_endfile (st_parameter_filepos *fpp) { st_parameter_dt dtp; dtp.common = fpp->common; - memset (&dtp.u.p.transfer, 0, sizeof (dtp.u.q)); + memset (&dtp.u.p, 0, sizeof (dtp.u.p)); dtp.u.p.current_unit = u; next_record (&dtp, 1); } diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c index 3b5f3f7..4134f16 100644 --- a/libgfortran/io/inquire.c +++ b/libgfortran/io/inquire.c @@ -43,7 +43,6 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u) { const char *p; GFC_INTEGER_4 cf = iqp->common.flags; - GFC_INTEGER_4 cf2 = iqp->flags2; if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0) { @@ -254,6 +253,8 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u) if (cf & IOPARM_INQUIRE_HAS_FLAGS2) { + GFC_INTEGER_4 cf2 = iqp->flags2; + if ((cf2 & IOPARM_INQUIRE_HAS_PENDING) != 0) *iqp->pending = 0; @@ -525,7 +526,6 @@ inquire_via_filename (st_parameter_inquire *iqp) { const char *p; GFC_INTEGER_4 cf = iqp->common.flags; - GFC_INTEGER_4 cf2 = iqp->flags2; if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0) *iqp->exist = file_exists (iqp->file, iqp->file_len); @@ -586,6 +586,8 @@ inquire_via_filename (st_parameter_inquire *iqp) if (cf & IOPARM_INQUIRE_HAS_FLAGS2) { + GFC_INTEGER_4 cf2 = iqp->flags2; + if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0) cf_strcpy (iqp->encoding, iqp->encoding_len, undefined); diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index ec37be3..1f36391 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -310,9 +310,9 @@ st_parameter_filepos; #define IOPARM_INQUIRE_HAS_ASYNCHRONOUS (1 << 0) #define IOPARM_INQUIRE_HAS_DECIMAL (1 << 1) #define IOPARM_INQUIRE_HAS_ENCODING (1 << 2) -#define IOPARM_INQUIRE_HAS_PENDING (1 << 3) -#define IOPARM_INQUIRE_HAS_ROUND (1 << 4) -#define IOPARM_INQUIRE_HAS_SIGN (1 << 5) +#define IOPARM_INQUIRE_HAS_ROUND (1 << 3) +#define IOPARM_INQUIRE_HAS_SIGN (1 << 4) +#define IOPARM_INQUIRE_HAS_PENDING (1 << 5) #define IOPARM_INQUIRE_HAS_SIZE (1 << 6) #define IOPARM_INQUIRE_HAS_ID (1 << 7) @@ -343,9 +343,9 @@ typedef struct CHARACTER1 (asynchronous); CHARACTER2 (decimal); CHARACTER1 (encoding); - CHARACTER2 (pending); - CHARACTER1 (round); - CHARACTER2 (sign); + CHARACTER2 (round); + CHARACTER1 (sign); + GFC_INTEGER_4 *pending; GFC_INTEGER_4 *size; GFC_INTEGER_4 *id; } @@ -377,172 +377,6 @@ struct format_data; #define IOPARM_DT_IONML_SET (1 << 31) -typedef struct st_parameter_43 -{ - void (*transfer) (struct st_parameter_dt *, bt, void *, int, - size_t, size_t); - struct gfc_unit *current_unit; - /* Item number in a formatted data transfer. Also used in namelist - read_logical as an index into line_buffer. */ - int item_count; - unit_mode mode; - unit_blank blank_status; - unit_sign sign_status; - int scale_factor; - int max_pos; /* Maximum righthand column written to. */ - /* Number of skips + spaces to be done for T and X-editing. */ - int skips; - /* Number of spaces to be done for T and X-editing. */ - int pending_spaces; - /* Whether an EOR condition was encountered. Value is: - 0 if no EOR was encountered - 1 if an EOR was encountered due to a 1-byte marker (LF) - 2 if an EOR was encountered due to a 2-bytes marker (CRLF) */ - int sf_seen_eor; - unit_advance advance_status; - unsigned reversion_flag : 1; /* Format reversion has occurred. */ - unsigned first_item : 1; - unsigned seen_dollar : 1; - unsigned eor_condition : 1; - unsigned no_leading_blank : 1; - unsigned char_flag : 1; - unsigned input_complete : 1; - unsigned at_eol : 1; - unsigned comma_flag : 1; - /* A namelist specific flag used in the list directed library - to flag that calls are being made from namelist read (eg. to - ignore comments or to treat '/' as a terminator) */ - unsigned namelist_mode : 1; - /* A namelist specific flag used in the list directed library - to flag read errors and return, so that an attempt can be - made to read a new object name. */ - unsigned nml_read_error : 1; - /* A sequential formatted read specific flag used to signal that a - character string is being read so don't use commas to shorten a - formatted field width. */ - unsigned sf_read_comma : 1; - /* A namelist specific flag used to enable reading input from - line_buffer for logical reads. */ - unsigned line_buffer_enabled : 1; - /* An internal unit specific flag used to identify that the associated - unit is internal. */ - unsigned unit_is_internal : 1; - /* An internal unit specific flag to signify an EOF condition for list - directed read. */ - unsigned at_eof : 1; - /* 16 unused bits. */ - - char last_char; - char nml_delim; - - int repeat_count; - int saved_length; - int saved_used; - bt saved_type; - char *saved_string; - char *scratch; - char *line_buffer; - struct format_data *fmt; - jmp_buf *eof_jump; - namelist_info *ionml; - /* A flag used to identify when a non-standard expanded namelist read - has occurred. */ - int expanded_read; - /* Storage area for values except for strings. Must be large - enough to hold a complex value (two reals) of the largest - kind. */ - char value[32]; - gfc_offset size_used; -} st_parameter_43; - - -typedef struct st_parameter_44 -{ - GFC_INTEGER_4 *id; - GFC_IO_INT pos; - CHARACTER1 (asynchronous); - CHARACTER2 (blank); - CHARACTER1 (decimal); - CHARACTER2 (delim); - CHARACTER1 (pad); - CHARACTER2 (round); - CHARACTER1 (sign); - void (*transfer) (struct st_parameter_dt *, bt, void *, int, - size_t, size_t); - struct gfc_unit *current_unit; - /* Item number in a formatted data transfer. Also used in namelist - read_logical as an index into line_buffer. */ - int item_count; - unit_mode mode; - unit_blank blank_status; - unit_sign sign_status; - int scale_factor; - int max_pos; /* Maximum righthand column written to. */ - /* Number of skips + spaces to be done for T and X-editing. */ - int skips; - /* Number of spaces to be done for T and X-editing. */ - int pending_spaces; - /* Whether an EOR condition was encountered. Value is: - 0 if no EOR was encountered - 1 if an EOR was encountered due to a 1-byte marker (LF) - 2 if an EOR was encountered due to a 2-bytes marker (CRLF) */ - int sf_seen_eor; - unit_advance advance_status; - unsigned reversion_flag : 1; /* Format reversion has occurred. */ - unsigned first_item : 1; - unsigned seen_dollar : 1; - unsigned eor_condition : 1; - unsigned no_leading_blank : 1; - unsigned char_flag : 1; - unsigned input_complete : 1; - unsigned at_eol : 1; - unsigned comma_flag : 1; - /* A namelist specific flag used in the list directed library - to flag that calls are being made from namelist read (eg. to - ignore comments or to treat '/' as a terminator) */ - unsigned namelist_mode : 1; - /* A namelist specific flag used in the list directed library - to flag read errors and return, so that an attempt can be - made to read a new object name. */ - unsigned nml_read_error : 1; - /* A sequential formatted read specific flag used to signal that a - character string is being read so don't use commas to shorten a - formatted field width. */ - unsigned sf_read_comma : 1; - /* A namelist specific flag used to enable reading input from - line_buffer for logical reads. */ - unsigned line_buffer_enabled : 1; - /* An internal unit specific flag used to identify that the associated - unit is internal. */ - unsigned unit_is_internal : 1; - /* An internal unit specific flag to signify an EOF condition for list - directed read. */ - unsigned at_eof : 1; - /* 16 unused bits. */ - - char last_char; - char nml_delim; - - int repeat_count; - int saved_length; - int saved_used; - bt saved_type; - char *saved_string; - char *scratch; - char *line_buffer; - struct format_data *fmt; - jmp_buf *eof_jump; - namelist_info *ionml; - /* A flag used to identify when a non-standard expanded namelist read - has occurred. */ - int expanded_read; - /* Storage area for values except for strings. Must be large - enough to hold a complex value (two reals) of the largest - kind. */ - char value[32]; - gfc_offset size_used; -} st_parameter_44; - typedef struct st_parameter_dt { st_parameter_common common; @@ -557,13 +391,97 @@ typedef struct st_parameter_dt to reserve enough space. */ union { - st_parameter_43 q; - st_parameter_44 p; + struct + { + void (*transfer) (struct st_parameter_dt *, bt, void *, int, + size_t, size_t); + struct gfc_unit *current_unit; + /* Item number in a formatted data transfer. Also used in namelist + read_logical as an index into line_buffer. */ + int item_count; + unit_mode mode; + unit_blank blank_status; + unit_sign sign_status; + int scale_factor; + int max_pos; /* Maximum righthand column written to. */ + /* Number of skips + spaces to be done for T and X-editing. */ + int skips; + /* Number of spaces to be done for T and X-editing. */ + int pending_spaces; + /* Whether an EOR condition was encountered. Value is: + 0 if no EOR was encountered + 1 if an EOR was encountered due to a 1-byte marker (LF) + 2 if an EOR was encountered due to a 2-bytes marker (CRLF) */ + int sf_seen_eor; + unit_advance advance_status; + unsigned reversion_flag : 1; /* Format reversion has occurred. */ + unsigned first_item : 1; + unsigned seen_dollar : 1; + unsigned eor_condition : 1; + unsigned no_leading_blank : 1; + unsigned char_flag : 1; + unsigned input_complete : 1; + unsigned at_eol : 1; + unsigned comma_flag : 1; + /* A namelist specific flag used in the list directed library + to flag that calls are being made from namelist read (eg. to + ignore comments or to treat '/' as a terminator) */ + unsigned namelist_mode : 1; + /* A namelist specific flag used in the list directed library + to flag read errors and return, so that an attempt can be + made to read a new object name. */ + unsigned nml_read_error : 1; + /* A sequential formatted read specific flag used to signal that a + character string is being read so don't use commas to shorten a + formatted field width. */ + unsigned sf_read_comma : 1; + /* A namelist specific flag used to enable reading input from + line_buffer for logical reads. */ + unsigned line_buffer_enabled : 1; + /* An internal unit specific flag used to identify that the associated + unit is internal. */ + unsigned unit_is_internal : 1; + /* An internal unit specific flag to signify an EOF condition for list + directed read. */ + unsigned at_eof : 1; + /* 16 unused bits. */ + + char last_char; + char nml_delim; + + int repeat_count; + int saved_length; + int saved_used; + bt saved_type; + char *saved_string; + char *scratch; + char *line_buffer; + struct format_data *fmt; + jmp_buf *eof_jump; + namelist_info *ionml; + /* A flag used to identify when a non-standard expanded namelist read + has occurred. */ + int expanded_read; + /* Storage area for values except for strings. Must be large + enough to hold a complex value (two reals) of the largest + kind. */ + char value[32]; + GFC_IO_INT size_used; + } p; /* This pad size must be equal to the pad_size declared in trans-io.c (gfc_build_io_library_fndecls). The above structure must be smaller or equal to this array. */ - char pad[32 * sizeof (char *) + 32 * sizeof (int)]; + char pad[16 * sizeof (char *) + 32 * sizeof (int)]; } u; + GFC_INTEGER_4 *id; + GFC_IO_INT pos; + CHARACTER1 (asynchronous); + CHARACTER2 (blank); + CHARACTER1 (decimal); + CHARACTER2 (delim); + CHARACTER1 (pad); + CHARACTER2 (round); + CHARACTER1 (sign); } st_parameter_dt; diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 500cce9..c4fae32 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -300,7 +300,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) dtp->u.p.current_unit->bytes_left -= *length; if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) - dtp->u.p.size_used += (gfc_offset) *length; + dtp->u.p.size_used += (GFC_IO_INT) *length; return base; } @@ -377,7 +377,7 @@ read_block_form (st_parameter_dt *dtp, void *buf, size_t *nbytes) } if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) - dtp->u.p.size_used += (gfc_offset) nread; + dtp->u.p.size_used += (GFC_IO_INT) nread; if (nread != *nbytes) { /* Short read, this shouldn't happen. */ @@ -625,7 +625,7 @@ write_block (st_parameter_dt *dtp, int length) } if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) - dtp->u.p.size_used += (gfc_offset) length; + dtp->u.p.size_used += (GFC_IO_INT) length; dtp->u.p.current_unit->strm_pos += (gfc_offset) length; @@ -1829,11 +1829,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL; - /* To maintain ABI, &transfer is the start of the private memory area in - in st_parameter_dt. Memory from the beginning of the structure to this - point is set by the front end and must not be touched. The number of - bytes to clear must stay within the sizeof q to avoid over-writing. */ - memset (&dtp->u.p.transfer, 0, sizeof (dtp->u.q)); + memset (&dtp->u.p, 0, sizeof (dtp->u.p)); dtp->u.p.ionml = ionml; dtp->u.p.mode = read_flag ? READING : WRITING; @@ -2077,7 +2073,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) /* Check the decimal mode. */ dtp->u.p.current_unit->decimal_status = !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED : - find_option (&dtp->common, dtp->u.p.decimal, dtp->u.p.decimal_len, + find_option (&dtp->common, dtp->decimal, dtp->decimal_len, decimal_opt, "Bad DECIMAL parameter in data transfer " "statement"); @@ -2087,7 +2083,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) /* Check the sign mode. */ dtp->u.p.sign_status = !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED : - find_option (&dtp->common, dtp->u.p.sign, dtp->u.p.sign_len, sign_opt, + find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt, "Bad SIGN parameter in data transfer statement"); if (dtp->u.p.sign_status == SIGN_UNSPECIFIED) @@ -2096,7 +2092,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) /* Check the blank mode. */ dtp->u.p.blank_status = !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED : - find_option (&dtp->common, dtp->u.p.blank, dtp->u.p.blank_len, + find_option (&dtp->common, dtp->blank, dtp->blank_len, blank_opt, "Bad BLANK parameter in data transfer statement"); @@ -2106,7 +2102,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) /* Check the delim mode. */ dtp->u.p.current_unit->delim_status = !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED : - find_option (&dtp->common, dtp->u.p.delim, dtp->u.p.delim_len, + find_option (&dtp->common, dtp->delim, dtp->delim_len, delim_opt, "Bad DELIM parameter in data transfer statement"); if (dtp->u.p.current_unit->delim_status == DELIM_UNSPECIFIED) @@ -2115,7 +2111,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) /* Check the pad mode. */ dtp->u.p.current_unit->pad_status = !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED : - find_option (&dtp->common, dtp->u.p.pad, dtp->u.p.pad_len, pad_opt, + find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt, "Bad PAD parameter in data transfer statement"); if (dtp->u.p.current_unit->pad_status == PAD_UNSPECIFIED) @@ -2858,7 +2854,7 @@ finalize_transfer (st_parameter_dt *dtp) GFC_INTEGER_4 cf = dtp->common.flags; if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) - *dtp->size = (GFC_IO_INT) dtp->u.p.size_used; + *dtp->size = dtp->u.p.size_used; if (dtp->u.p.eor_condition) { |