diff options
author | Janne Blomqvist <jblomqvi@cc.hut.fi> | 2004-06-22 03:43:55 +0300 |
---|---|---|
committer | Paul Brook <pbrook@gcc.gnu.org> | 2004-06-22 00:43:55 +0000 |
commit | 8750f9cdec153095cc47c41b887bc86fda4a0e3e (patch) | |
tree | ceecaee98023a95b8e6865056ce0fa2cc4afb927 /gcc/fortran | |
parent | 88c499cce7487e1d4b40e8c7d568db22ba59d90e (diff) | |
download | gcc-8750f9cdec153095cc47c41b887bc86fda4a0e3e.zip gcc-8750f9cdec153095cc47c41b887bc86fda4a0e3e.tar.gz gcc-8750f9cdec153095cc47c41b887bc86fda4a0e3e.tar.bz2 |
re PR fortran/15750 (IOLENGTH form of INQUIRE statement not implemented)
PR fortran/15750
* io.c (gfc_match_inquire): Bugfix for iolength related stuff.
(gfc_resolve_inquire): Resolve the iolength tag. Return
SUCCESS at end of function if no failure has occured.
* resolve.c (resolve_code): Resolve if iolength is encountered.
* trans-io.c: (ioparm_iolength, iocall_iolength,
iocall_iolength_done): New variables.
(last_dt): Add IOLENGTH.
(gfc_build_io_library_fndecls ): Set iolength related variables.
(gfc_trans_iolength): Implement.
(gfc_trans_dt_end): Treat iolength as a third form of data transfer.
libgfortran/
PR fortran/15750
* inquire.c (st_inquire): Add comment
* io.h (st_parameter): Add iolength.
(st_iolength, st_iolength_done): Declare.
* transfer.c (iolength_transfer, iolength_transfer_init,
st_iolength, st_iolength_done): New functions.
testsuite/
* gfortran.fortran-torture/execute/iolength_1.f90: New test.
* gfortran.fortran-torture/execute/iolength_3.f90: New test.
From-SVN: r83472
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/fortran/io.c | 5 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 9 | ||||
-rw-r--r-- | gcc/fortran/trans-io.c | 89 |
4 files changed, 101 insertions, 16 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 41c9a90..0114728 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,17 @@ +2004-06-22 Janne Blomqvist <jblomqvi@cc.hut.fi> + + PR fortran/15750 + * io.c (gfc_match_inquire): Bugfix for iolength related stuff. + (gfc_resolve_inquire): Resolve the iolength tag. Return + SUCCESS at end of function if no failure has occured. + * resolve.c (resolve_code): Resolve if iolength is encountered. + * trans-io.c: (ioparm_iolength, iocall_iolength, + iocall_iolength_done): New variables. + (last_dt): Add IOLENGTH. + (gfc_build_io_library_fndecls ): Set iolength related variables. + (gfc_trans_iolength): Implement. + (gfc_trans_dt_end): Treat iolength as a third form of data transfer. + 2004-06-21 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de PR fortran/15511 diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index 56cbe87..ee52c69 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -2353,7 +2353,7 @@ gfc_match_inquire (void) new_st.op = EXEC_IOLENGTH; new_st.expr = inquire->iolength; - gfc_free (inquire); + new_st.ext.inquire = inquire; if (gfc_pure (NULL)) { @@ -2439,9 +2439,10 @@ gfc_resolve_inquire (gfc_inquire * inquire) RESOLVE_TAG (&tag_readwrite, inquire->readwrite); RESOLVE_TAG (&tag_s_delim, inquire->delim); RESOLVE_TAG (&tag_s_pad, inquire->pad); + RESOLVE_TAG (&tag_iolength, inquire->iolength); if (gfc_reference_st_label (inquire->err, ST_LABEL_TARGET) == FAILURE) return FAILURE; - return FAILURE; + return SUCCESS; } diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 77ac3d4..03851f5 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -3452,7 +3452,6 @@ resolve_code (gfc_code * code, gfc_namespace * ns) { case EXEC_NOP: case EXEC_CYCLE: - case EXEC_IOLENGTH: case EXEC_PAUSE: case EXEC_STOP: case EXEC_EXIT: @@ -3620,6 +3619,14 @@ resolve_code (gfc_code * code, gfc_namespace * ns) case EXEC_INQUIRE: if (gfc_resolve_inquire (code->ext.inquire) == FAILURE) + break; + + resolve_branch (code->ext.inquire->err, code); + break; + + case EXEC_IOLENGTH: + assert(code->ext.inquire != NULL); + if (gfc_resolve_inquire (code->ext.inquire) == FAILURE) break; resolve_branch (code->ext.inquire->err, code); diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c index c0570fc..3f4076f 100644 --- a/gcc/fortran/trans-io.c +++ b/gcc/fortran/trans-io.c @@ -59,6 +59,7 @@ static GTY(()) tree ioparm_nextrec; static GTY(()) tree ioparm_size; static GTY(()) tree ioparm_recl_in; static GTY(()) tree ioparm_recl_out; +static GTY(()) tree ioparm_iolength; static GTY(()) tree ioparm_file; static GTY(()) tree ioparm_file_len; static GTY(()) tree ioparm_status; @@ -124,6 +125,8 @@ static GTY(()) tree iocall_x_complex; static GTY(()) tree iocall_open; static GTY(()) tree iocall_close; static GTY(()) tree iocall_inquire; +static GTY(()) tree iocall_iolength; +static GTY(()) tree iocall_iolength_done; static GTY(()) tree iocall_rewind; static GTY(()) tree iocall_backspace; static GTY(()) tree iocall_endfile; @@ -136,7 +139,7 @@ static GTY(()) tree iocall_set_nml_val_log; /* Variable for keeping track of what the last data transfer statement was. Used for deciding which subroutine to call when the data transfer is complete. */ -static enum { READ, WRITE } last_dt; +static enum { READ, WRITE, IOLENGTH } last_dt; #define ADD_FIELD(name, type) \ ioparm_ ## name = gfc_add_field_to_struct \ @@ -187,6 +190,8 @@ gfc_build_io_library_fndecls (void) ADD_FIELD (recl_in, gfc_pint4_type_node); ADD_FIELD (recl_out, gfc_pint4_type_node); + ADD_FIELD (iolength, gfc_pint4_type_node); + ADD_STRING (file); ADD_STRING (status); @@ -282,6 +287,10 @@ gfc_build_io_library_fndecls (void) gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")), gfc_int4_type_node, 0); + iocall_iolength = + gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")), + void_type_node, 0); + iocall_rewind = gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")), gfc_int4_type_node, 0); @@ -302,6 +311,11 @@ gfc_build_io_library_fndecls (void) iocall_write_done = gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")), gfc_int4_type_node, 0); + + iocall_iolength_done = + gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")), + gfc_int4_type_node, 0); + iocall_set_nml_val_int = gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_int")), void_type_node, 4, @@ -793,16 +807,6 @@ gfc_trans_inquire (gfc_code * code) } -/* Translate the IOLENGTH form of an INQUIRE statement. We treat - this as a third sort of data transfer statement, except that - lengths are summed instead of actually transfering any data. */ - -tree -gfc_trans_iolength (gfc_code * c ATTRIBUTE_UNUSED) -{ - gfc_todo_error ("IOLENGTH statement"); -} - static gfc_expr * gfc_new_nml_name_expr (char * name) { @@ -858,6 +862,8 @@ build_dt (tree * function, gfc_code * code) set_error_locus (&block, &code->loc); dt = code->ext.dt; + assert (dt != NULL); + if (dt->io_unit) { if (dt->io_unit->ts.type == BT_CHARACTER) @@ -973,6 +979,41 @@ build_dt (tree * function, gfc_code * code) } +/* Translate the IOLENGTH form of an INQUIRE statement. We treat + this as a third sort of data transfer statement, except that + lengths are summed instead of actually transfering any data. */ + +tree +gfc_trans_iolength (gfc_code * code) +{ + stmtblock_t block; + gfc_inquire *inq; + tree dt; + + gfc_init_block (&block); + + set_error_locus (&block, &code->loc); + + inq = code->ext.inquire; + + /* First check that preconditions are met. */ + assert(inq != NULL); + assert(inq->iolength != NULL); + + /* Connect to the iolength variable. */ + if (inq->iolength) + set_parameter_ref (&block, ioparm_iolength, inq->iolength); + + /* Actual logic. */ + last_dt = IOLENGTH; + dt = build_dt(&iocall_iolength, code); + + gfc_add_expr_to_block (&block, dt); + + return gfc_finish_block (&block); +} + + /* Translate a READ statement. */ tree @@ -1005,12 +1046,33 @@ gfc_trans_dt_end (gfc_code * code) gfc_init_block (&block); - function = (last_dt == READ) ? iocall_read_done : iocall_write_done; + switch (last_dt) + { + case READ: + function = iocall_read_done; + break; + + case WRITE: + function = iocall_write_done; + break; + + case IOLENGTH: + function = iocall_iolength_done; + break; + + default: + abort (); + } tmp = gfc_build_function_call (function, NULL); gfc_add_expr_to_block (&block, tmp); - io_result (&block, code->ext.dt->err, code->ext.dt->end, code->ext.dt->eor); + if (last_dt != IOLENGTH) + { + assert(code->ext.dt != NULL); + io_result (&block, code->ext.dt->err, + code->ext.dt->end, code->ext.dt->eor); + } return gfc_finish_block (&block); } @@ -1087,6 +1149,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr) tmp = gfc_build_function_call (function, args); gfc_add_expr_to_block (&se->pre, tmp); gfc_add_block_to_block (&se->pre, &se->post); + } |