On 16/08/07, Diego Novillo <[EMAIL PROTECTED]> wrote:
> On 8/16/07 6:18 AM, Manuel López-Ibáñez wrote:
>
> That's right.  In this case variable 'i' is an addressable local, so it
> is not put in normal SSA form.  It's in virtual SSA form (use the -vops
> option when dumping the IL).  We don't warn on memory symbols, only
> registers.
>
> One way to address this could be to consider 'i.0' uninitialized because
> its initial value is coming from a local memory symbol with no know
> initialization.  Notice that the initial assignment to i.0 has a VUSE
> for i's default definition.  You could probably use that to warn that
> 'i' is being used uninitialized.

This patch fixes gcc.dg/uninit-B.c:

=====================================
--- gcc/tree-ssa.c      (revision 126606)
+++ gcc/tree-ssa.c      (working copy)
@@ -1205,7 +1205,7 @@
 /* Emit a warning for T, an SSA_NAME, being uninitialized.  The exact
   warning text is in MSGID and LOCUS may contain a location or be null.  */

-static void
+void
 warn_uninit (tree t, const char *gmsgid, void *data)
 {
  tree var = SSA_NAME_VAR (t);
@@ -1217,8 +1217,40 @@
  /* Default uses (indicated by an empty definition statement),
     are uninitialized.  */
  if (!IS_EMPTY_STMT (def))
+    {
+        /* Otherwise, it may be an initial assignment that has a VUSE
+           to a variable's default definition.  */
+        if (TREE_CODE (def) == GIMPLE_MODIFY_STMT
+            && has_stmt_ann (def)
+            && ssa_operands_active ()
+            && stmt_references_memory_p (def))
+        {
+          struct voptype_d *vuses = VUSE_OPS (def);
+          while (vuses)
+            {
+              int i;
+              int n = VUSE_NUM (vuses);
+              for (i = 0; i < n; i++)
+                {
+                  if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
+                    warn_uninit (VUSE_OP (vuses, i),
+                             "%H%qD is used uninitialized in this function",
+                                 def);
+                }
+              vuses = vuses->next;
+            }
+        }
+      return;
+    }
+
+  /* We don't warn for global variables or memory tags. */
+  if (MTAG_P (var) || !is_gimple_variable (var)
+      || !is_gimple_reg_type (TREE_TYPE (var))
+      || TREE_THIS_VOLATILE (var)
+      || is_global_var (var))
    return;

+
  /* Except for PARMs of course, which are always initialized.  */
  if (TREE_CODE (var) == PARM_DECL)
    return;

However, it gives new false positives. I don't see how can I
differentiate between the two following examples. When i.0D.1284_2 =
iD.1283; is analyzed by warn_uninit, the situation looks exactly the
same to me.

f ()
{
 intD.0 iD.1283;
 intD.0 i.0D.1284;

 # BLOCK 0, starting at line 8
 # PRED: ENTRY (fallthru)
 [doublereference-2.c : 8] g (&iD.1283);
 #   VUSE <iD.1283_1>;
 [doublereference-2.c : 9] i.0D.1284_2 = iD.1283;
 [doublereference-2.c : 9] h (i.0D.1284_2);
 [doublereference-2.c : 10] return;
 # SUCC: EXIT

}

f ()
{
 intD.0 iD.1283;
 intD.0 i.0D.1284;

 # BLOCK 0, starting at line 7
 # PRED: ENTRY (fallthru)
 #   VUSE <iD.1283_1>;
 [doublereference-3.c : 7] i.0D.1284_2 = iD.1283;
 [doublereference-3.c : 7] h (i.0D.1284_2);
 [doublereference-3.c : 8] g (&iD.1283);
 [doublereference-3.c : 9] return;
 # SUCC: EXIT
}

Am I missing something?

Cheers,

Manuel.

Reply via email to