diff options
author | Mikael Morin <mikael@gcc.gnu.org> | 2012-07-26 08:53:56 +0000 |
---|---|---|
committer | Mikael Morin <mikael@gcc.gnu.org> | 2012-07-26 08:53:56 +0000 |
commit | b63b1f862611aa41662d7cd7027d040dc6682f57 (patch) | |
tree | d21fdd8c66cb49708b7bfb8eb3be677f1dec8cb3 /gcc/fortran | |
parent | ca27d5aebd6c4a4fb2776f2924da621c26b5fd1a (diff) | |
download | gcc-b63b1f862611aa41662d7cd7027d040dc6682f57.zip gcc-b63b1f862611aa41662d7cd7027d040dc6682f57.tar.gz gcc-b63b1f862611aa41662d7cd7027d040dc6682f57.tar.bz2 |
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
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 46 |
2 files changed, 35 insertions, 18 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3c68cbf..0c0ffe0 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 ba108dc..555d696 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 |