Commit b63b1f86 by Mikael Morin

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
parent ca27d5ae
2012-07-26 Mikael Morin <mikael@gcc.gnu.org> 2012-07-26 Mikael Morin <mikael@gcc.gnu.org>
PR fortran/44354 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. * array.c (sought_symbol): New variable.
(expr_is_sought_symbol_ref, find_symbol_in_expr): New functions. (expr_is_sought_symbol_ref, find_symbol_in_expr): New functions.
(resolve_array_list): Check for references to the induction (resolve_array_list): Check for references to the induction
......
...@@ -1520,6 +1520,9 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, ...@@ -1520,6 +1520,9 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
bool dynamic) bool dynamic)
{ {
tree tmp; tree tmp;
tree start = NULL_TREE;
tree end = NULL_TREE;
tree step = NULL_TREE;
stmtblock_t body; stmtblock_t body;
gfc_se se; gfc_se se;
mpz_t size; mpz_t size;
...@@ -1542,8 +1545,30 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, ...@@ -1542,8 +1545,30 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
expression in an interface mapping. */ expression in an interface mapping. */
if (c->iterator) if (c->iterator)
{ {
gfc_symbol *sym = c->iterator->var->symtree->n.sym; gfc_symbol *sym;
tree type = gfc_typenode_for_spec (&sym->ts); 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"); shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar); gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
...@@ -1678,8 +1703,6 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, ...@@ -1678,8 +1703,6 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
/* Build the implied do-loop. */ /* Build the implied do-loop. */
stmtblock_t implied_do_block; stmtblock_t implied_do_block;
tree cond; tree cond;
tree end;
tree step;
tree exit_label; tree exit_label;
tree loopbody; tree loopbody;
tree tmp2; tree tmp2;
...@@ -1691,20 +1714,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, ...@@ -1691,20 +1714,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
gfc_start_block(&implied_do_block); gfc_start_block(&implied_do_block);
/* Initialize the loop. */ /* Initialize the loop. */
gfc_init_se (&se, NULL); gfc_add_modify (&implied_do_block, shadow_loopvar, start);
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);
/* If this array expands dynamically, and the number of iterations /* If this array expands dynamically, and the number of iterations
is not constant, we won't have allocated space for the static is not constant, we won't have allocated space for the static
......
2012-07-26 Mikael Morin <mikael@gcc.gnu.org> 2012-07-26 Mikael Morin <mikael@gcc.gnu.org>
PR fortran/44354 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. * gfortran.dg/array_constructor_38.f90: New test.
2012-07-25 Janis Johnson <janisjo@codesourcery.com> 2012-07-25 Janis Johnson <janisjo@codesourcery.com>
......
! { 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment