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

Reply via email to