On Wed, Jun 24, 2026 at 12:17 PM Tomasz Kamiński <[email protected]> wrote:
> 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, They achieve that, by simply checking a non-default spec first, and then using default impl. Nothing special is really required to reach that state. > 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 > >
