Bug 47623

Summary: [4.4/4.5/4.6 Regression] false *negative* uninitialized warning
Product: gcc Reporter: Zack Weinberg <zack+srcbugz>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: manu, rguenth
Priority: P3    
Version: 4.5.2   
Target Milestone: ---   
Host: Target:
Build: Known to work: 4.3.5
Known to fail: Last reconfirmed: 2011-02-06 18:11:40

Description Zack Weinberg 2011-02-06 17:51:25 UTC
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.
Comment 1 Manuel López-Ibáñez 2011-02-06 20:25:13 UTC
If this testcase works in GCC 4.3.5 is just by chance. This is the old PR18501. There is plenty of analysis, discussion and proposals there for anyone interested in giving it a try.

*** This bug has been marked as a duplicate of bug 18501 ***
Comment 2 H.J. Lu 2011-02-06 21:32:29 UTC
This regression is triggered by revision 133341:

http://gcc.gnu.org/ml/gcc-cvs/2008-03/msg00560.html