https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89888
Bug ID: 89888
Summary: When switch controlling expression is promoted from
type narrower than int, GCC does not diagnose
identical cases
Product: gcc
Version: 8.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: pascal_cuoq at hotmail dot com
Target Milestone: ---
Consider the C function:
long long X;
void f(unsigned char x)
{
switch(x) {
case -1: X=-1; break;
case 0xffffffff: X=0xffffffff; break;
}
}
The controlling expression of the switch, x, has type unsigned char and is
promoted to int before its type being used as reference for the constants -1
and 0xffffffff. This is according to C11 6.8.4.2:5
(https://port70.net/~nsz/c/c11/n1570.html#6.8.4.2p5 )
GCC 8.3 emits very good warnings about each of the constants being, after
conversion, outside the range of an unsigned int and thus unreachable:
<source>: In function 'f':
<source>:6:5: warning: case label value is less than minimum value for type
case -1: X=-1; break;
^~~~
<source>:7:5: warning: case label value is less than minimum value for type
case 0xffffffff: X=0xffffffff; break;
^~~~
(Compiler Explorer link: https://gcc.godbolt.org/z/gvnvoa )
However, GCC does not warn about the labels being identical after conversion. I
feel silly reporting this, because it only happens for discarded labels that
were unreachable, and there isn't any ambiguity about the meaning of the
program. Still, the C11 clause 6.8.4.2:3 about identical switch case labels
(after conversion) (https://port70.net/~nsz/c/c11/n1570.html#6.8.4.2p3 ) is
under a “Constraints” heading, so depending how much GCC cares about adhering
to the letter of the standard, it may want to diagnose this situation.
Clang diagnoses this situation and emits an “error”:
<source>:7:10: error: duplicate case value '-1'
Clang also emits two misleading warnings about the constants -1 and 0xffffffff.
The wording of these warnings is so misleading that it can be considered a
Clang bug, which has been reported in the appropriate place.