Hi Jakub,

I investigated the source of the macro further.

I am not defining `__BFLT16_DIG__` in the project command line, in a
user header, or in the source before including libstdc++ headers.

The diagnostic is produced by CLion 2023.3.6's bundled JetBrains clangd
18 when parsing a WSL project configured with `/usr/bin/c++` (GCC
14.2.0). `std::format` is first marked as erroneous in the user source;
following that diagnostic into `<format>` leads to:

```
else if constexpr (is_same_v<_Td, decltype(0.0bf16)>)
```

where clangd reports:

```
invalid suffix 'bf16' on floating constant
```

Consequently, uses that depend on `<format>`, including
`make_format_args`, are also marked as erroneous.

I enabled CLion's clangd protocol logging and found that CLion supplies
GCC's predefined macro set to clangd through an `-imacros` file. The
actual clangd command contains:

```
-imacros /mnt/x/clion_clangd_inmemory_directory/macros/...
```

and the contents of that virtual macro file include:

```
#define __GNUC__ 14
#define __GNUC_MINOR__ 2
#define __BFLT16_MANT_DIG__ 8
#define __BFLT16_DIG__ 2
```

Thus the `__BFLT16_DIG__`-guarded code is visible to clangd because
CLion injects the predefined macros collected from the selected GCC
toolchain. The same JetBrains clangd run standalone with an ordinary
GCC-style compile command, without CLion's injected `-imacros` file,
does not define `__BFLT16_DIG__` and does not reach this code.

So the issue is a mismatch: clangd is given GCC's bfloat16 capability
macros but does not recognize the corresponding `bf16` literal suffix.

Separately, I understand your point that `__bf16` cannot be assumed to
be the type of `0.0bf16` on every target. My proposed change to
`c++config` was checked on x86_64.

And maybe the previous commit is better?

Sincerely,
Jakit

Jakub Jelinek <[email protected]> 于2026年9月7日周一 22:16写道:
>
> On Mon, Sep 07, 2026 at 09:59:04PM +0800, Jakit Liang wrote:
> > Tested on x86_64-linux-gnu with g++ and clangd 18/19.
> >
> > Signed-off-by: Jakit Liang <[email protected]>
> > ---
> >  libstdc++-v3/include/bits/c++config | 2 +-
> >  libstdc++-v3/include/std/format     | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/bits/c++config 
> > b/libstdc++-v3/include/bits/c++config
> > index 60456a48681..072da451df8 100644
> > --- a/libstdc++-v3/include/bits/c++config
> > +++ b/libstdc++-v3/include/bits/c++config
> > @@ -892,7 +892,7 @@ namespace std
> >  #if defined __cplusplus && defined __BFLT16_DIG__
> >  namespace __gnu_cxx
> >  {
> > -  typedef __decltype(0.0bf16) __bfloat16_t;
> > +  typedef __bf16 __bfloat16_t;
>
> This is incorrect.
>
> __bf16 is the type of 0.0bf16 literals only on some targets, not all.
> You haven't explained why is __BFLT16_DIG__ defined when compiling with
> clangd, it shouldn't be when it doesn't support bfloat16_t properly.
> Are you defining it by hand on the command line or in some user header
> or main source before including the libstdc++ headers?
>
>         Jakub
>

Reply via email to