Skip to content

i686: libstdc++ 15 headers fail with "__gnu_cxx has no member __bfloat16_t" (missing __BFLT16_* predefined macros) #511

Open

Description

@daveedvdv-nvidia

In the edg_x86_32 test configuration (the gcc-i686 base, which uses the
system libstdc++ 15 headers with -m32), any test that includes <meta> (or
another header that pulls in <type_traits>, <cmath>, <ostream>, etc.)
fails to compile in C++23/C++26 mode:

"/usr/include/c++/15/type_traits", line 514: error: namespace "__gnu_cxx" has no member "__bfloat16_t"
      struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t>
                                                   ^

"/usr/include/c++/15/bits/cpp_type_traits.h", line 348: error: namespace "__gnu_cxx" has no member "__bfloat16_t"
      struct __is_floating<__gnu_cxx::__bfloat16_t>
                                      ^
...
8 errors detected in the compilation of "Test_name.c".

So far this has been papered over by recording the failure:
reflections/demo1 has a .demo1.rto/edg_x86_32.1.1.txt recording and a
FAIL(COMPILE) entry in tests/expectations/edg_x86_32/reflections.log, and
the new reflection tests in #241 need the same treatment. That means the
reflection tests effectively don't run on i686.

Cause

libstdc++ uses and defines the type under different conditions:

  • The specializations above are guarded by #ifdef __STDCPP_BFLOAT16_T__, which
    the front end predefines whenever extended floating-point types are enabled
    (src/macro.c).

  • The typedef itself, in bits/c++config.h (both the 64-bit one and the
    32/ multilib one), is guarded by __BFLT16_DIG__:

    #if defined __cplusplus && defined __BFLT16_DIG__
    namespace __gnu_cxx
    {
      typedef __decltype(0.0bf16) __bfloat16_t;
    }
    #endif

bases/docker/dev-env/gcc/lib_linux_x86_64/predefined_macros.txt defines
__BFLT16_DIG__ (and the other __BFLT16_* and __FLT16_* macros) in GNU
mode, but lib_linux_i686/predefined_macros.txt (identical in the gcc and
gcc-i686 bases, unchanged since the initial release) has none of them. Yet
GCC 15 predefines them with -m32 too:

$ echo | g++ -m32 -std=c++23 -dM -E -x c++ - | grep -E 'BFLT16_DIG|FLT16_DIG'
#define __BFLT16_DIG__ 2
#define __FLT16_DIG__ 3

Possible fix

Add the __BFLT16_* and __FLT16_* entries that GCC predefines with -m32 to
lib_linux_i686/predefined_macros.txt, mirroring the gnu entries in the
x86-64 file. Then re-record the affected edg_x86_32 recordings
(reflections/demo1 and the tests from #241) and drop their FAIL entries
from tests/expectations/edg_x86_32/.

Also worth checking: plain g++ -m32 (no SSE2) does not define
__STDCPP_BFLOAT16_T__, while the front end always does when extended
floating-point types are enabled. With __BFLT16_DIG__ defined, libstdc++'s
uses become consistent again, so that difference may not matter in practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions