[RFC] PR middle-end/179 gcc -O2 -Wuninitialized missing warning with &var
Richard Guenther
richard.guenther@gmail.com
Mon Aug 11 14:54:00 GMT 2008
On Mon, Aug 11, 2008 at 3:15 PM, Manuel López-Ibáñez
<lopezibanez@gmail.com> wrote:
> This is an initial attempt to handle VOPs in -Wuninitialized. Taking
> the address of a variable messes up uninitialized warnings because
> VOPs are completely ignored. The following patch tries to detect one
> particular case [http://gcc.gnu.org/ml/gcc/2007-08/msg00273.html]:
>
> extern void foo (int *);
> extern void bar (int);
>
> void
> baz (void)
> {
> int i;
> if (i) /* { dg-warning "uninit" "uninit i warning" { xfail *-*-* } } */
> bar (i);
> foo (&i);
> }
>
> For this example we create something like:
>
> baz (void) {
> intD.0 iD.1283;
> intD.0 i.0D.1284;
>
> # BLOCK 0, starting at line 7
> # PRED: ENTRY (fallthru)
> # VUSE <iD.1283_1>;
> i.0D.1284_2 = iD.1283;
>
>
> And that is exactly what the new code tries to detect. I try hard to
> ignore every other case because they generate false positives while
> bootstrapping.
>
> Any comments? Can we do this better? Can the new code give false positives?
I think it is useful - however
+ if (TYPE_MODE (TREE_TYPE (var)) == BLKmode)
+ return false;
+
+ if (is_call_clobbered (var))
+ {
+ var_ann_t va = var_ann (var);
+ unsigned int escape_mask = va->escape_mask;
+ if (escape_mask & ESCAPE_TO_ASM)
+ return false;
+ if (escape_mask & ESCAPE_IS_GLOBAL)
+ return false;
+ if (escape_mask & ESCAPE_IS_PARM)
+ return false;
+ }
this should be not necessary at all (in fact I believe just excluding
PARM_DECLs and is_global_var should be enough).
Also the following
if (!ssa_undefined_value_p (t))
- return;
+ {
+ /*struct voptype_d *vdefs;*/
+ struct voptype_d *vuses;
+ /* Recurse into SSA virtual operands to check whether T is using
+ a VDEF with default definition or it is VUSing another
+ uninitialized variable. */
+ gimple def = SSA_NAME_DEF_STMT (t);
+ tree op;
- /* TREE_NO_WARNING either means we already warned, or the front end
- wishes to suppress the warning. */
- if (TREE_NO_WARNING (var))
+ if (!gimple_references_memory_p (def))
+ return;
+
+ vuses = gimple_vuse_ops (def);
+ while (vuses)
+ {
+ int i, n;
just should use
def_stmt = SSA_NAME_DEF_STMT (t);
FOR_EACH_SSA_USE_OPERAND (..., def_stmt, ..., SSA_OP_VIRTUAL_USES)
if (ssa_maybe_uninitialized_var_p (SSA_NAME_VAR (USE_FROM_PTR (use)))
warn ...
note that there may be false positives from like
int *p, *q;
int foo (int b)
{
int i, j = 0;
int *x;
p = &i;
q = &j;
if (b)
x = &p;
else
x = &q;
return *x;
}
if you pass in false only it will warn because *x may access
uninitialized i. So in the end you may want to omit warnings
from defining load statements that load via a pointer. Note
that using VOPs only works for the late uninitialized pass
(aliasing is not computed before). Note also that using VOPs
is unreliable due to partitioning, etc., a better way is to iterate
over the LOADED_SYMS bitmap of the defining statement
(doesn't work for calls!) - this would work for the early pass as well.
Richard.
More information about the Gcc-patches
mailing list