summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-26 08:53:56 +0000
committermikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-26 08:53:56 +0000
commit58018be108017ac524caff06dfcf4c7818122d60 (patch)
treed21fdd8c66cb49708b7bfb8eb3be677f1dec8cb3
parent487dc8b20bb4c0c4845128793c566901ba2752ed (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/fortran/trans-array.c46
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_39.f9013
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
+