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
This commit is contained in:
Mikael Morin 2012-07-26 08:53:56 +00:00
parent ca27d5aebd
commit b63b1f8626
4 changed files with 53 additions and 18 deletions

View file

@ -1,3 +1,10 @@
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

View file

@ -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

View file

@ -1,3 +1,8 @@
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

View file

@ -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