https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127383
Bug ID: 127383
Summary: [C23 _BitInt] wrong code for complement of unsigned
_BitInt(63) converted to unsigned long long
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: shimizu2486 at gmail dot com
Target Milestone: ---
Live Reproducer: https://godbolt.org/z/vs6vMccM1
Storing a signed _BitInt(N) into a struct member, where N does not fill its
container, gives the wrong value from -O2 up.
$ cat t1.c
#include <stdio.h>
struct { unsigned _BitInt(65) f : 63; } s;
int main(void) {
unsigned long long w = ~(unsigned _BitInt(63))s.f;
printf("%llu\n", w);
}
$ gcc -O0 t1.c -o t1 && ./t1
18446744073709551615 (wrong)
$ clang -O0 t1.c -o t1 && ./t1
9223372036854775807 (correct)
In C23 semantics, w should be 9223372036854775807 (2^63 - 1), but the actual
output is 2^64 - 1
This micompilation manifests in all optimization levels, including -O0 .
This miscompilation persists against all gcc versions that supports C23 _BitInt
.
Because this happens on O0 as well, I suspect the root cause is in C frontend.
The program does not trigger UB.