From b63b1f862611aa41662d7cd7027d040dc6682f57 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Thu, 26 Jul 2012 08:53:56 +0000 Subject: [PATCH] re PR fortran/44354 (implied do loop with its own variable name as upper bound) fortran/ PR fortran/44354 * trans-array.c (gfc_trans_array_constructor_value): Evaluate the iteration bounds before the inner variable shadows the outer. testsuite/ PR fortran/44354 * gfortran.dg/array_constructor_39.f90: New test. From-SVN: r189883 --- gcc/fortran/ChangeLog | 7 +++ gcc/fortran/trans-array.c | 46 +++++++++++-------- gcc/testsuite/ChangeLog | 5 ++ .../gfortran.dg/array_constructor_39.f90 | 13 ++++++ 4 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/array_constructor_39.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3c68cbfdc33..0c0ffe05458 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2012-07-26 Mikael Morin + + PR fortran/44354 + * trans-array.c (gfc_trans_array_constructor_value): + Evaluate the iteration bounds before the inner variable shadows + the outer. + 2012-07-26 Mikael Morin PR fortran/44354 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index ba108dc7e75..555d69696bb 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -1520,6 +1520,9 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, bool dynamic) { tree tmp; + tree start = NULL_TREE; + tree end = NULL_TREE; + tree step = NULL_TREE; stmtblock_t body; gfc_se se; mpz_t size; @@ -1542,8 +1545,30 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, expression in an interface mapping. */ if (c->iterator) { - gfc_symbol *sym = c->iterator->var->symtree->n.sym; - tree type = gfc_typenode_for_spec (&sym->ts); + gfc_symbol *sym; + tree type; + + /* Evaluate loop bounds before substituting the loop variable + in case they depend on it. Such a case is invalid, but it is + not more expensive to do the right thing here. + See PR 44354. */ + gfc_init_se (&se, NULL); + gfc_conv_expr_val (&se, c->iterator->start); + gfc_add_block_to_block (pblock, &se.pre); + start = gfc_evaluate_now (se.expr, pblock); + + gfc_init_se (&se, NULL); + gfc_conv_expr_val (&se, c->iterator->end); + gfc_add_block_to_block (pblock, &se.pre); + end = gfc_evaluate_now (se.expr, pblock); + + gfc_init_se (&se, NULL); + gfc_conv_expr_val (&se, c->iterator->step); + gfc_add_block_to_block (pblock, &se.pre); + step = gfc_evaluate_now (se.expr, pblock); + + sym = c->iterator->var->symtree->n.sym; + type = gfc_typenode_for_spec (&sym->ts); shadow_loopvar = gfc_create_var (type, "shadow_loopvar"); gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar); @@ -1678,8 +1703,6 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, /* Build the implied do-loop. */ stmtblock_t implied_do_block; tree cond; - tree end; - tree step; tree exit_label; tree loopbody; tree tmp2; @@ -1691,20 +1714,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, gfc_start_block(&implied_do_block); /* Initialize the loop. */ - gfc_init_se (&se, NULL); - gfc_conv_expr_val (&se, c->iterator->start); - gfc_add_block_to_block (&implied_do_block, &se.pre); - gfc_add_modify (&implied_do_block, shadow_loopvar, se.expr); - - gfc_init_se (&se, NULL); - gfc_conv_expr_val (&se, c->iterator->end); - gfc_add_block_to_block (&implied_do_block, &se.pre); - end = gfc_evaluate_now (se.expr, &implied_do_block); - - gfc_init_se (&se, NULL); - gfc_conv_expr_val (&se, c->iterator->step); - gfc_add_block_to_block (&implied_do_block, &se.pre); - step = gfc_evaluate_now (se.expr, &implied_do_block); + gfc_add_modify (&implied_do_block, shadow_loopvar, start); /* If this array expands dynamically, and the number of iterations is not constant, we won't have allocated space for the static diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 16d56aee9bf..254bf802d8d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-26 Mikael Morin + + PR fortran/44354 + * gfortran.dg/array_constructor_39.f90: New test. + 2012-07-26 Mikael Morin PR fortran/44354 diff --git a/gcc/testsuite/gfortran.dg/array_constructor_39.f90 b/gcc/testsuite/gfortran.dg/array_constructor_39.f90 new file mode 100644 index 00000000000..83eff05ddca --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_constructor_39.f90 @@ -0,0 +1,13 @@ +! { dg-do run } +! +! PR fortran/44354 +! array constructors were giving unexpected results when the ac-implied-do +! variable was used in one of the ac-implied-do bounds. +! +! Original testcase by Vittorio Zecca +! + I=5 + if (any((/(i,i=1,I)/) /= (/1,2,3,4,5/))) call abort ! { dg-warning "final expression references control variable" } + if (I /= 5) call abort + end +