aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2012-07-26 08:53:56 +0000
committerMikael Morin <mikael@gcc.gnu.org>2012-07-26 08:53:56 +0000
commitb63b1f862611aa41662d7cd7027d040dc6682f57 (patch)
treed21fdd8c66cb49708b7bfb8eb3be677f1dec8cb3 /gcc/fortran
parentca27d5aebd6c4a4fb2776f2924da621c26b5fd1a (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/fortran/trans-array.c46
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