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.

Reply via email to