http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47623

           Summary: false *negative* uninitialized warning
           Product: gcc
           Version: 4.5.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: za...@panix.com


Consider

    int foo(int x)
    {
       int a;
       if (x) return a;
       return 0;
    }

This function should trigger the "‘a’ may be used uninitialized" warning when
compiled with -O -Wall, but it doesn't; there are no diagnostics at all.  The
assembly output (x86-64) is just

foo:
    movl    $0, %eax
    ret

Looking at optimization dumps, this is what we have right before CCP1:

    foo (int x)
    {
      int a;

    <bb 2>:
      if (x_2(D) != 0)
        goto <bb 3>;
      else
        goto <bb 4>;

    <bb 3>:
      a_4 = a_3(D);
      goto <bb 5>;

    <bb 4>:
      a_5 = 0;

    <bb 5>:
      # a_1 = PHI <a_4(3), a_5(4)>
      return a_1;
    }

but right *after* CCP1, we have instead

    <bb 5>:
      # a_1 = PHI <a_4(3), 0(4)>
      return 0;

-- I presume that CCP notices that one of the inputs to the PHI is undefined
and ignores that possibility under the "well, if that happened, there would be
undefined behavior, so we can assume that can't happen" principle.  CDDCE1 then
erases the remainder of the code and we're left with

    foo (int x)
    {
    <bb 2>:
      return 0;
    }

which has no uninitialized variable accesses, of course.  I'm not sure exactly
where uninitialized warnings happen these days, but clearly it's after this
point.

As far as a fix, I recommend either that any pass that can make use of the
"that variable is uninitialized so we're going to ignore the possibility of
that control path" principle should emit -Wuninitialized warnings, or (my
personal preference) we scrap the notion of doing -Wuninitialized from inside
the optimizers, and switch to something predictable, like Java's definite
assignment rules.

Reply via email to