[Bug c/124699] New: [9/10/11/12/13] Expression using __builtin_ffsll() may not be considered constant

matt at mtcoster dot net gcc-bugzilla@gcc.gnu.org
Mon Mar 30 14:50:30 GMT 2026


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

            Bug ID: 124699
           Summary: [9/10/11/12/13] Expression using __builtin_ffsll() may
                    not be considered constant
           Product: gcc
           Version: 13.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: matt at mtcoster dot net
  Target Milestone: ---

Tested on releases/gcc-13@e1dd4a37ba2. I can also reproduce on any build of 9
through 13, with <=8 being generally unhappy about the construct in the test
case and >=14 not complaining about the constant-ness of the expression.

I've bisected the "fix" between 13 and 14 branch points to commit 0d00385eaf7
("wide-int: Allow up to 16320 bits wide_int and change widest_int precision to
32640 bits [PR102989]").

I also spent a long time getting the reproduction case as minimal as possible,
as the original discovery was significantly complicated by the use of Linux
kernel macros:
https://lore.kernel.org/oe-kbuild-all/202603222211.A2XiR1YU-lkp@intel.com/. In
the test case below, almost any subtle change will cause GCC to evaluate the
expression as constant.

The tentative workaround I intend to propose for Linux is to add a (long long)
cast to the argument of __builtin_ffsll() where the value may come from a
constant with the ULL suffix.

> $ cat test.i
> # 0 "test.c"
> # 0 "<built-in>"
> # 0 "<command-line>"
> # 1 "/usr/include/stdc-predef.h" 1 3 4
> # 0 "<command-line>" 2
> # 1 "test.c"
> int main() {
>  sizeof(struct {
>   _Static_assert(__builtin_ffsll(~0ULL) + 1 < 0);
>  });
> }

> $ /opt/gcc/bin/gcc -v -save-temps -o test test.c
> Using built-in specs.
> COLLECT_GCC=/opt/gcc/bin/gcc
> COLLECT_LTO_WRAPPER=/opt/gcc/libexec/gcc/aarch64-unknown-linux-gnu/13.4.1/lto-wrapper
> Target: aarch64-unknown-linux-gnu
> Configured with: ../configure --prefix=/opt/gcc --enable-languages=c
> Thread model: posix
> Supported LTO compression algorithms: zlib zstd
> gcc version 13.4.1 20260323 (GCC)
> COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-mlittle-endian' '-mabi=lp64'
>  /opt/gcc/libexec/gcc/aarch64-unknown-linux-gnu/13.4.1/cc1 -E -quiet -v -imultiarch aarch64-linux-gnu test.c -mlittle-endian -mabi=lp64 -fpch-preprocess -o test.i
> ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
> ignoring nonexistent directory "/opt/gcc/lib/gcc/aarch64-unknown-linux-gnu/13.4.1/include-fixed/aarch64-linux-gnu"
> ignoring nonexistent directory "/opt/gcc/lib/gcc/aarch64-unknown-linux-gnu/13.4.1/../../../../aarch64-unknown-linux-gnu/include"
> #include "..." search starts here:
> #include <...> search starts here:
>  /opt/gcc/lib/gcc/aarch64-unknown-linux-gnu/13.4.1/include
>  /usr/local/include
>  /opt/gcc/include
>  /opt/gcc/lib/gcc/aarch64-unknown-linux-gnu/13.4.1/include-fixed
>  /usr/include/aarch64-linux-gnu
>  /usr/include
> End of search list.
> COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-mlittle-endian' '->mabi=lp64'
>  /opt/gcc/libexec/gcc/aarch64-unknown-linux-gnu/13.4.1/cc1 -fpreprocessed test.i -quiet -dumpbase test.c -dumpbase-ext .c -mlittle-endian -mabi=lp64 -version -o test.s
> GNU C17 (GCC) version 13.4.1 20260323 (aarch64-unknown-linux-gnu)
> 	compiled by GNU C version 13.4.1 20260323, GMP version 6.3.0, MPFR >version 4.2.2, MPC version 1.3.1, isl version isl-0.27-GMP
>
> GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
> Compiler executable checksum: 9c2a43a44f8dcc0692afda9d7d2fe2dc
> test.c: In function 'main':
> test.c:3:59: error: expression in static assertion is not constant
>     3 |                 _Static_assert(__builtin_ffsll(~0ULL) + 1 < 0);
>       |                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~

In any build of GCC including the above mentioned commit, the error message
changes to:

> test:3:17: error: static assertion failed
>     3 |                 _Static_assert(__builtin_ffsll(~0ULL) + 1 < 0);
>       |                 ^~~~~~~~~~~~~~

The more complicated case reported by the kernel test bot (linked above) is
more critical, since the static assertion would not otherwise fail had the
expression been correctly evaluated as constant. I was unable to put together
such a simple test case that demonstrated this behaviour though.


More information about the Gcc-bugs mailing list