]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/44354 (implied do loop with its own variable name as upper bound)
authorMikael Morin <mikael@gcc.gnu.org>
Thu, 26 Jul 2012 08:53:56 +0000 (08:53 +0000)
committerMikael Morin <mikael@gcc.gnu.org>
Thu, 26 Jul 2012 08:53:56 +0000 (08:53 +0000)
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

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/array_constructor_39.f90 [new file with mode: 0644]

index 3c68cbfdc33c8d421d00c746e52c9d0f69e8b2d1..0c0ffe054589ea899a6bbaf3ab35f56b826e3299 100644 (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
index ba108dc7e75b54172e3099b0d4f843ba40d2471d..555d69696bb829d51409f9b23a6a51b7959d4e2b 100644 (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
index 16d56aee9bfcb41aa5c6ccf5684401346022ce10..254bf802d8da2f5e5364ceaf232056f0466159f9 100644 (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
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_39.f90 b/gcc/testsuite/gfortran.dg/array_constructor_39.f90
new file mode 100644 (file)
index 0000000..83eff05
--- /dev/null
@@ -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
+