With -O2, versions of gcc going as far back as 4.5.3 all the way to recent trunk (6.0) issues a -Wmaybe-uninitialized warning for the code below. The bug appears to be masking a large number of problems in glibc (see https://sourceware.org/bugzilla/show_bug.cgi?id=19444). $ (cc=$HOME/bin/gcc-5.1.0/bin/gcc; cat a.c && set -x && $cc -S -o/dev/null -O1 -Wall -Wextra a.c && $cc -O2 -S -Wall -Wextra -o/dev/null a.c) int foo (int i) { int j; switch (i & 2) { case 0: j = 1; break; case 1: j = 2; break; case 2: j = 3; break; case 3: j = 4; break; } return j + 1; } + /home/msebor/bin/gcc-5.1.0/bin/gcc -S -o/dev/null -O1 -Wall -Wextra a.c a.c: In function ‘foo’: a.c:11:12: warning: ‘j’ may be used uninitialized in this function [-Wmaybe-uninitialized] return j + 1; ^ + /home/msebor/bin/gcc-5.1.0/bin/gcc -O2 -S -Wall -Wextra -o/dev/null a.c
switch (i & 2) i & 2 is either 0 or 2. there is a case for both 0 and 2 in the switch statement. So this is invalid.
The glibc test case is actually closer to the following (I had made a typo in the bitwise AND expression). When (i == 4), j is never assigned to. int foo (int i) { int j; switch (i & 3) { case 0: j = 1; break; case 1: j = 2; break; case 2: j = 3; break; case 3: j = 4; break; } return j + 1; } For reference, an example of glibc code where this causes a problem is here: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/ieee754/dbl-64/e_jn.c#l103
This new testcase is still broken as i & 3 is 0, 1, 2 or 3. All of the case statements are there too. So if you want to say something the bug is in -O1 which should not warn instead. But that requires VRP which is what figures out i & 3 to have a range of [0,3] and that only runs at -O2. There is still no bug for -O2 here. GCC is correct those j is initialized on all paths.
My bad. I confused the decimal 3 for a binary 111. Gcc does warn both ways when the controlling expression is (i & 7) so the problem is the other way around. Thanks for the correction. I suppose this really is invalid since the GCC manual notes the -O1 caveat for a similar case, and glibc should either not be built with -Wmaybe-uninitialized and -O1 or it should add a default case to the switch.