http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58455
--- Comment #2 from Roland Dreier <rbd at debian dot org> --- Arg, I don't seem to be able to avoid breaking my test cases while minimizing them. So for my first test case here the issue seems to be that -Og is the only level that *correctly* warns, which is surprising and I guess is a bug in it's own right! Sorry for the confusion. However the test case I was originally working with and then broke is the following: $ cat y.cpp struct B { int offset; bool is_loaded(unsigned char *p1) { if (offset) { *p1 = offset; return true; } return false; } }; unsigned char match(struct B ref) { do { unsigned char ref_offset; if (!ref.is_loaded(&ref_offset) || false) continue; return ref_offset; } while (false); return 0; } $ for o in Og O0 O1 O2 O3; do echo == $o ==; gcc -Wall -$o -Werror -c ~/y.cpp; done == Og == /home/roland/y.cpp: In function ‘unsigned char match(B)’: /home/roland/y.cpp:17:31: error: ‘ref_offset’ may be used uninitialized in this function [-Werror=maybe-uninitialized] unsigned char ref_offset; ^ cc1plus: all warnings being treated as errors == O0 == == O1 == == O2 == == O3 == in that case is_loaded returns true when it sets the pointer; if it returns false we continue, fall out of the loop and don't touch the pointer value. So I'm pretty sure this case is correctly classified as spurious.