diff options
author | mikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-26 08:53:56 +0000 |
---|---|---|
committer | mikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-26 08:53:56 +0000 |
commit | 58018be108017ac524caff06dfcf4c7818122d60 (patch) | |
tree | d21fdd8c66cb49708b7bfb8eb3be677f1dec8cb3 | |
parent | 487dc8b20bb4c0c4845128793c566901ba2752ed (diff) | |
download | gcc-58018be108017ac524caff06dfcf4c7818122d60.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189883 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/fortran/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 46 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/array_constructor_39.f90 | 13 |
4 files changed, 53 insertions, 18 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3c68cbfdc33..0c0ffe05458 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,6 +1,13 @@ 2012-07-26 Mikael Morin <mikael@gcc.gnu.org> 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 <mikael@gcc.gnu.org> + + PR fortran/44354 * array.c (sought_symbol): New variable. (expr_is_sought_symbol_ref, find_symbol_in_expr): New functions. (resolve_array_list): Check for references to the induction 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,6 +1,11 @@ 2012-07-26 Mikael Morin <mikael@gcc.gnu.org> PR fortran/44354 + * gfortran.dg/array_constructor_39.f90: New test. + +2012-07-26 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/44354 * gfortran.dg/array_constructor_38.f90: New test. 2012-07-25 Janis Johnson <janisjo@codesourcery.com> 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 <zeccav@gmail.com> +! + 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 + |