https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121693

            Bug ID: 121693
           Summary: forgets to clear the padding bits when converting a
                    _BitInt(1) on x86_64
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vincent-gcc at vinc17 dot net
  Target Milestone: ---

The x86_64 psABI https://gitlab.com/x86-psABIs/x86-64-ABI says about _BitInt:
"The value of the unused bits beyond the width of the _BitInt(N) value but
within the size of the _BitInt(N) are unspecified when stored in memory or
register."

So it is valid to read a _BitInt(N) with nonzero padding bits. However, GCC
does not clear them (contrary to Clang).

Testcase:

#include <stdio.h>

typedef union
{
  _Bool b;
  unsigned char c;
  unsigned _BitInt(1) i;
} T;

int main (void)
{
  T v;
  volatile char c = 2;
  v.c = c;
  printf ("%d %d\n", (int) v.i, (int) (_Bool) (int) v.i);
  return 0;
}

With the -O option, gcc (Debian 20250804-1) 16.0.0 20250804 (experimental)
[master r16-2729-g0d276cd378e] outputs "2 2" instead of "0 0" (ditto if
-fsanitize=undefined -fno-sanitize-recover are also used and with GCC 14.3.0).

The fact that the conversion to _Bool does not give 0 or 1 for the second value
shows that GCC is already confused by the v.i value.

Reply via email to