libstdc++: Correct preprocessing checks for floatX_t and bfloat_16 formatting
Floating points types _Float16, _Float32, _Float64, and bfloat16, can be formatted only if std::to_chars overloads for such types were provided. Currently this is only the case for architectures 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. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
parent
2ac842a1e8
commit
445128c12c
1 changed files with 8 additions and 24 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue