https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107465
Bug ID: 107465
Summary: Bogus warning: promoted bitwise complement of an
unsigned value is always nonzero
Product: gcc
Version: 11.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: lavr at ncbi dot nlm.nih.gov
Target Milestone: ---
Tried on both Ubuntu and Cygwin, the same gcc-11.3.0 -- and the same problem:
$ gcc --version
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc --version
gcc (GCC) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The code:
$ cat test.c
extern void fun2(void);
#ifdef BOGUS_WARNING
typedef unsigned short uint2;
#else
#define uint2 unsigned short
#endif
static void fun(uint2 x)
{
if (!(x ^ 0xFFFF))
fun2();
}
int main(void)
{
fun(0);
}
The compilation:
$ gcc -Wall -Wextra -O6 -c test.c
(clean)
BUT:
$ gcc -Wall -Wextra -O6 -c -DBOGUS_WARNING test.c
test.c: In function ‘fun’:
test.c:11:9: warning: promoted bitwise complement of an unsigned value is
always nonzero [-Wsign-compare]
11 | if (!(x ^ 0xFFFF))
| ^
The variable "x" is an unsigned short, so it gets promoted to int without the
sign extension; the second argument to XOR is a 32-bit int with only 16 bits
set to 1. The result of XOR is not necessarily non-0 because it does not flip
all the bits in an int, but only the lower 16 (so there's no promotion of any
sort, IMO). Also, it's weird that the warning is only issued with a typedef
for the type of "x".