Bug 29458

Summary: Spurious -Wuninitialized warning for implied do-loop counter
Product: gcc Reporter: Francois-Xavier Coudert <fxcoudert>
Component: fortranAssignee: Daniel Franke <dfranke>
Status: RESOLVED FIXED    
Severity: normal CC: anlauf, gcc-bugs, manu, tjf
Priority: P3 Keywords: diagnostic
Version: 4.2.0   
Target Milestone: 4.5.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2009-04-05 13:20:02
Bug Depends on:    
Bug Blocks: 24639    

Description Francois-Xavier Coudert 2006-10-13 14:03:20 UTC
$ cat a.f90
  integer :: n, i
  n = 5
  n = sum((/(i,i=1,n)/))
  end
$ gfortran -O -Wall a.f90
a.f90: In function ‘MAIN__’:
a.f90:3: warning: ‘i’ is used uninitialized in this function
Comment 1 Francois-Xavier Coudert 2007-01-31 23:01:50 UTC
This is fixed by the following patch:

Index: trans-array.c
===================================================================
--- trans-array.c       (revision 121280)
+++ trans-array.c       (working copy)
@@ -1280,6 +1280,7 @@
          gfc_conv_expr (&se, c->iterator->var);
          gfc_add_block_to_block (pblock, &se.pre);
          loopvar = se.expr;
+         TREE_NO_WARNING(loopvar) = 1;
 
          /* Make a temporary, store the current value in that
             and return it, once the loop is done.  */
Comment 2 Andrew Pinski 2007-01-31 23:07:36 UTC
Why not create a new i for the inner loop instead of saving it off?
Or is:
  integer :: n, i
  n = 5
  n = sum((/(i,i=1,f())/))
contains
  function f()
  integer :: f
  f = i+1
  end

valid and well defined?
Comment 3 kargls 2007-04-27 22:18:02 UTC
*** Bug 31731 has been marked as a duplicate of this bug. ***
Comment 4 Mark Mitchell 2007-05-14 22:26:39 UTC
Will not be fixed in 4.2.0; retargeting at 4.2.1.
Comment 5 Francois-Xavier Coudert 2007-08-12 20:15:48 UTC
(In reply to comment #2)
> Why not create a new i for the inner loop instead of saving it off?

This is indeed what we should do; however, I can't find a way to work it out. Unassigning myself.
Comment 6 tjf 2007-11-16 20:57:27 UTC
I'd just like to remind everyone that this is still an issue in gcc version 4.3.0 20071109
Comment 7 Brian Barnes 2008-01-30 17:18:30 UTC
This bug also shows up when executing the example code for initializing random_seed in the gfortran documentation.  Is it a regression w.r.t.  4.0 or 4.1?  Maybe not, but it would be nice if something in the docs didn't generate a warning ;)
Comment 8 kargls 2008-01-30 19:26:16 UTC
(In reply to comment #7)
> This bug also shows up when executing the example code for initializing
> random_seed in the gfortran documentation.  Is it a regression w.r.t.  4.0 or
> 4.1?  Maybe not, but it would be nice if something in the docs didn't generate
> a warning ;)

No, it is not a regression w.r.t to any previous version of gfortran.
The problem has always existed.  You're more than welcomed to fix it.

Comment 9 Manuel López-Ibáñez 2008-01-30 19:53:29 UTC
I tried this:

Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c   (revision 131893)
+++ gcc/fortran/trans-array.c   (working copy)
@@ -1246,36 +1246,27 @@ gfc_trans_array_constructor_value (stmtb
          tree end;
          tree step;
          tree loopvar;
          tree exit_label;
          tree loopbody;
-         tree tmp2;
-         tree tmp_loopvar;

          loopbody = gfc_finish_block (&body);

          if (c->iterator->var->symtree->n.sym->backend_decl)
            {
-             gfc_init_se (&se, NULL);
-             gfc_conv_expr (&se, c->iterator->var);
-             gfc_add_block_to_block (pblock, &se.pre);
-             loopvar = se.expr;
+             loopvar = gfc_typenode_for_spec (&c->iterator->var->ts);
+             loopvar = gfc_create_var (loopvar, c->iterator->var->symtree->n.sym->name);
            }
          else
            {
              /* If the iterator appears in a specification expression in
                 an interface mapping, we need to make a temp for the loop
                 variable because it is not declared locally.  */
              loopvar = gfc_typenode_for_spec (&c->iterator->var->ts);
              loopvar = gfc_create_var (loopvar, "loopvar");
            }

-         /* Make a temporary, store the current value in that
-            and return it, once the loop is done.  */
-         tmp_loopvar = gfc_create_var (TREE_TYPE (loopvar), "loopvar");
-         gfc_add_modify_expr (pblock, tmp_loopvar, loopvar);
-
          /* Initialize the loop.  */
          gfc_init_se (&se, NULL);
          gfc_conv_expr_val (&se, c->iterator->start);
          gfc_add_block_to_block (pblock, &se.pre);
          gfc_add_modify_expr (pblock, loopvar, se.expr);
@@ -1293,10 +1284,12 @@ gfc_trans_array_constructor_value (stmtb
          /* If this array expands dynamically, and the number of iterations
             is not constant, we won't have allocated space for the static
             part of C->EXPR's size.  Do that now.  */
          if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
            {
+             tree tmp2;
+
              /* Get the number of iterations.  */
              tmp = gfc_get_iteration_count (loopvar, end, step);

              /* Get the static part of C->EXPR's size.  */
              gfc_get_array_constructor_element_size (&size, c->expr);
@@ -1339,13 +1332,10 @@ gfc_trans_array_constructor_value (stmtb
          gfc_add_expr_to_block (pblock, tmp);

          /* Add the exit label.  */
          tmp = build1_v (LABEL_EXPR, exit_label);
          gfc_add_expr_to_block (pblock, tmp);
-
-         /* Restore the original value of the loop counter.  */
-         gfc_add_modify_expr (pblock, loopvar, tmp_loopvar);
        }
     }
   mpz_clear (size);
 }


But something is still using the wrong 'i':

   <D.937>:;
    if (i.4D.918 > D.919)
      {
        goto L.1D.922;
      }
    else
      {

      }
    D.932 = atmp.2D.915.dataD.906;
    D.938 = (integer(kind=4)D.8[0] *) D.932;
    offset.6D.939 = offset.3D.917;
    (*D.938)[offset.6D.939] = iD.902; <<===== This is the wrong "i"!!
    offset.3D.917 = offset.3D.917 + 1;
    i.4D.918 = i.4D.918 + 1;
    goto <D.937>;

I also give up. Too time-consuming understanding what is going on...
Comment 10 Manuel López-Ibáñez 2008-01-30 20:13:18 UTC
For my classification of -Wuninitialized problems (see http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings), this is caused by a representation issue.
Comment 11 Daniel Franke 2009-04-05 13:20:02 UTC
Patch:
  http://gcc.gnu.org/ml/fortran/2009-04/msg00035.html
Comment 12 Daniel Franke 2009-04-05 18:02:13 UTC
Subject: Bug 29458

Author: dfranke
Date: Sun Apr  5 18:02:00 2009
New Revision: 145564

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145564
Log:
gcc/fortran/:
2009-04-05  Daniel Franke  <franke.daniel@gmail.com>

        PR fortran/29458
        * trans-array.c (gfc_trans_array_constructor_value): Shadow implied
        do-loop variable to avoid spurious middle-end warnings.


gcc/testsuite/:
2009-04-05  Daniel Franke  <franke.daniel@gmail.com>

        PR fortran/29458
        * gfortran.dg/implied_do_1.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/implied_do_1.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/testsuite/ChangeLog

Comment 13 Daniel Franke 2009-04-05 18:04:17 UTC
Fixed in trunk. Backport unlikely as it's not a regression. Closing.