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.