If the new _Pres_type values are introduced for given type, they may
lead to unrecognized _Pres_type values, if the TU using them is
linked with TU compiled with older releases, and format from old
TU is selected.

For most of the formatters, the default implementation is used as the
fallback, however __formatter_int and __formatter_fp were treating
that as UB, due to call to __builtin_unreachable in default branch
the switch. This patch addresses above by fallbacking _Pres_none
behavior in such case.

Note that this for C++20 affects programs using non-Unicode literal
encoding, as __do_vformat_to is exported from the library otherwise,
and thus newest version is always picked.

libstdc++-v3/ChangeLog:

        * include/std/format (__formatter_int::format)
        (__formatter_fp::format): For unrecognised _M_spec._M_type
        values (default branch of switch) fallthrou to _Pres_none.
---
Separate patch adding _Pres_p/_Pres_P incomming.
Testing on x86_64-linux. OK for trunk and GCC-16?

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

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 3a083f68030..2bd1d4aa1fb 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1722,6 +1722,7 @@ namespace __format
            case _Pres_c:
              return _M_format_character(_S_to_character(__i), __fc);
 #endif
+           default: // Fallback for _Pres_type values introduces in later 
versions.
            case _Pres_none:
              // Should not reach here with _Pres_none for bool or charT, so:
              [[fallthrough]];
@@ -1741,8 +1742,6 @@ namespace __format
                for (auto __p = __start; __p != __res.ptr; ++__p)
                  *__p = __format::__toupper_numeric(*__p);
              break;
-           default:
-             __builtin_unreachable();
          }
 
          if (_M_spec._M_alt && __base_prefix.size())
@@ -2172,12 +2171,11 @@ namespace __format
              __use_prec = true;
              __fmt = chars_format::general;
              break;
+           default: // Fallback for _Pres_type values introduces in later 
versions.
            case _Pres_none:
              if (__use_prec)
                __fmt = chars_format::general;
              break;
-           default:
-             __builtin_unreachable();
          }
 
          // Write value into buffer using std::to_chars.
-- 
2.54.0

Reply via email to