aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-io.c
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2009-06-07 18:57:43 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2009-06-07 18:57:43 +0000
commit9ad55c33ae2d0c410fbc563fd59e8edb37a48b8b (patch)
treee2b0715b914cdb097c8b193771d9487252906c00 /gcc/fortran/trans-io.c
parent690aefeba465a8fc85b779fa56d24ad892f17281 (diff)
downloadgcc-9ad55c33ae2d0c410fbc563fd59e8edb37a48b8b.zip
gcc-9ad55c33ae2d0c410fbc563fd59e8edb37a48b8b.tar.gz
gcc-9ad55c33ae2d0c410fbc563fd59e8edb37a48b8b.tar.bz2
re PR fortran/40008 (F2008: Add NEWUNIT= for OPEN statement)
2009-05-31 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/40008 * gfortran.h (gfc_open): Add newunit expression to structure. * io.c (io_tag): Add new unit tag and fix whitespace. (match_open_element): Add matching for newunit. (gfc_free_open): Free the newunit expression. (gfc_resolve_open): Add newunit to resolution and check constraints. (gfc_resolve_close): Add check for non-negative unit. (gfc_resolve_filepos): Likewise. (gfc_resolve_dt): Likewise. * trans-io.c (set_parameter_value): Build runtime checks for unit numbers within range of kind=4 integer. (gfc_trans_open) Set the newunit parameter. * ioparm.def (IOPARM): Define the newunit parameter as a pointer to GFC_INTEGER_4, pint4. From-SVN: r148252
Diffstat (limited to 'gcc/fortran/trans-io.c')
-rw-r--r--gcc/fortran/trans-io.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index 0acf632..bdd70f5 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -469,26 +469,27 @@ set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
gfc_conv_expr_val (&se, e);
/* If we're storing a UNIT number, we need to check it first. */
- if (type == IOPARM_common_unit && e->ts.kind != 4)
+ if (type == IOPARM_common_unit && e->ts.kind > 4)
{
- tree cond, max;
+ tree cond, val;
int i;
/* Don't evaluate the UNIT number multiple times. */
se.expr = gfc_evaluate_now (se.expr, &se.pre);
- /* UNIT numbers should be nonnegative. */
+ /* UNIT numbers should be greater than the min. */
+ i = gfc_validate_kind (BT_INTEGER, 4, false);
+ val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].pedantic_min_int, 4);
cond = fold_build2 (LT_EXPR, boolean_type_node, se.expr,
- build_int_cst (TREE_TYPE (se.expr),0));
+ fold_convert (TREE_TYPE (se.expr), val));
gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
- "Negative unit number in I/O statement",
+ "Unit number in I/O statement too small",
&se.pre);
/* UNIT numbers should be less than the max. */
- i = gfc_validate_kind (BT_INTEGER, 4, false);
- max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
+ val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
cond = fold_build2 (GT_EXPR, boolean_type_node, se.expr,
- fold_convert (TREE_TYPE (se.expr), max));
+ fold_convert (TREE_TYPE (se.expr), val));
gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
"Unit number in I/O statement too large",
&se.pre);
@@ -950,6 +951,10 @@ gfc_trans_open (gfc_code * code)
if (p->convert)
mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
p->convert);
+
+ if (p->newunit)
+ mask |= set_parameter_ref (&block, &post_block, var, IOPARM_open_newunit,
+ p->newunit);
set_parameter_const (&block, var, IOPARM_common_flags, mask);