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.

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 (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.

Signed-off-by: Tomasz Kamiński <tkami...@redhat.com>

---
GCC 13 didn't define formatters for _FloatXX_t types, as they were added
in r14-3305-g6cf214b4fc97f5 that allowed extended floating point types
to be formated before C++23. I think the remaining part of patch is
still revelant for C++23.
Do we still want to backport? OK for 13?


 
 libstdc++-v3/include/std/format | 24 ++++--------------------
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index f46012a2b01..c7e43330e7e 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -2979,22 +2979,16 @@ namespace __format
 
          // TODO bfloat16 and float16
 
-#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>)
@@ -3074,16 +3068,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.49.0

Reply via email to