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.