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.