On Wed, Mar 12, 2025 at 1:00 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> On Tue, 11 Mar 2025 at 12:22, Tomasz Kamiński wrote:
> >
> > Floating points types _Float16, _Float32, _Float64, and bfloat16,
> > can be formatted only if std::to_chars overloads for such types
> > where provided. Currently this is only the case for architectures
>
> Spelling: "were provided"
>
> With that fixed, OK for trunk, thanks for noticing this.
>
> I think we also want this on the gcc-14 and gcc-13 branches, but after
> it's sat on trunk for a while.
>
OK to backport to both now?

>
> > where float and double are 32-bits and 64-bits IEEE floating points
> types.
> >
> > This patch updates the preprocessing checks for formatters
> > for above types to check _GLIBCXX_FLOAT_IS_IEEE_BINARY32
> > and _GLIBCXX_DOUBLE_IS_IEEE_BINARY64. Making them non-formattable
> > on non-IEEE architectures.
> >
> > Remove a potential UB, where we could produce basic_format_arg
> > with _M_type set to _Arg_fp32 or _Arg_fp64, that was later not
> > handled by `_M_visit`.
> >
> > libstdc++-v3/ChangeLog:
> >
> >         * include/std/format (formatter<_Float16, _CharT>): Define only
> if
> >         _GLIBCXX_FLOAT_IS_IEEE_BINARY32 macro is defined.
> >         (formatter<_Float16, _CharT>): As above.
> >         (formatter<__gnu_cxx::__bfloat16_t, _CharT>): As above.
> >         (formatter<_Float64, _CharT>): Define only if
> >         _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 is defined.
> >         (basic_format_arg::_S_to_arg_type): Normalize _Float32 and
> _Float64
> >         only to float and double respectivelly.
> >         (basic_format_arg::_S_to_enum): Remove handling of _Float32 and
> _Float64.
> > ---
> > Tested on x86_64-linux. OK for trunk?
> >
> >  libstdc++-v3/include/std/format | 32 ++++++++------------------------
> >  1 file changed, 8 insertions(+), 24 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/std/format
> b/libstdc++-v3/include/std/format
> > index e7e0d2d142b..1809f040077 100644
> > --- a/libstdc++-v3/include/std/format
> > +++ b/libstdc++-v3/include/std/format
> > @@ -2276,7 +2276,7 @@ namespace __format
> >      };
> >  #endif
> >
> > -#ifdef __STDCPP_FLOAT16_T__
> > +#if defined(__STDCPP_FLOAT16_T__) &&
> defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
> >    // Reuse __formatter_fp<C>::format<float, Out> for _Float16.
> >    template<__format::__char _CharT>
> >      struct formatter<_Float16, _CharT>
> > @@ -2298,7 +2298,7 @@ namespace __format
> >      };
> >  #endif
> >
> > -#if defined(__FLT32_DIG__)
> > +#if defined(__FLT32_DIG__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
> >    // Reuse __formatter_fp<C>::format<float, Out> for _Float32.
> >    template<__format::__char _CharT>
> >      struct formatter<_Float32, _CharT>
> > @@ -2320,7 +2320,7 @@ namespace __format
> >      };
> >  #endif
> >
> > -#if defined(__FLT64_DIG__)
> > +#if defined(__FLT64_DIG__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
> >    // Reuse __formatter_fp<C>::format<double, Out> for _Float64.
> >    template<__format::__char _CharT>
> >      struct formatter<_Float64, _CharT>
> > @@ -2364,7 +2364,7 @@ namespace __format
> >      };
> >  #endif
> >
> > -#ifdef __STDCPP_BFLOAT16_T__
> > +#if defined(__STDCPP_BFLOAT16_T__) &&
> defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
> >    // Reuse __formatter_fp<C>::format<float, Out> for bfloat16_t.
> >    template<__format::__char _CharT>
> >      struct formatter<__gnu_cxx::__bfloat16_t, _CharT>
> > @@ -3443,22 +3443,16 @@ namespace __format
> >             return type_identity<float>();
> >  #endif
> >
> > -#ifdef __FLT32_DIG__
> > +#if defined(__FLT32_DIG__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
> >           else if constexpr (is_same_v<_Td, _Float32>)
> > -# ifdef _GLIBCXX_FLOAT_IS_IEEE_BINARY32
> >             return type_identity<float>();
> > -# else
> > -           return type_identity<_Float32>();
> > -# endif
> >  #endif
> > -#ifdef __FLT64_DIG__
> > +
> > +#if defined(__FLT64_DIG__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
> >           else if constexpr (is_same_v<_Td, _Float64>)
> > -# ifdef _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
> >             return type_identity<double>();
> > -# else
> > -           return type_identity<_Float64>();
> > -# endif
> >  #endif
> > +
> >  #if _GLIBCXX_FORMAT_F128
> >  # if __FLT128_DIG__
> >           else if constexpr (is_same_v<_Td, _Float128>)
> > @@ -3538,16 +3532,6 @@ namespace __format
> >             return _Arg_u128;
> >  #endif
> >
> > -         // N.B. some of these types will never actually be used here,
> > -         // because they get normalized to a standard floating-point
> type.
> > -#if defined __FLT32_DIG__ && ! _GLIBCXX_FLOAT_IS_IEEE_BINARY32
> > -         else if constexpr (is_same_v<_Tp, _Float32>)
> > -           return _Arg_f32;
> > -#endif
> > -#if defined __FLT64_DIG__ && ! _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
> > -         else if constexpr (is_same_v<_Tp, _Float64>)
> > -           return _Arg_f64;
> > -#endif
> >  #if _GLIBCXX_FORMAT_F128 == 2
> >           else if constexpr (is_same_v<_Tp, __format::__float128_t>)
> >             return _Arg_f128;
> > --
> > 2.48.1
> >
>
>

Reply via email to