https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119246

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <tkami...@gcc.gnu.org>:

https://gcc.gnu.org/g:9c9a7316adb99693e237164908893a78b86ba000

commit r16-616-g9c9a7316adb99693e237164908893a78b86ba000
Author: Tomasz KamiÅski <tkami...@redhat.com>
Date:   Wed Apr 30 10:37:48 2025 +0200

    libstdc++: Preserve the argument type in basic_format_args [PR119246]

    This commits adjust the way how the arguments are stored in the _Arg_value
    (and thus basic_format_args), by preserving the types of fixed width
    floating-point types, that were previously converted to float, double,
    long double.

    The _Arg_value union now contains alternatives with std::bfloat16_t,
    std::float16_t, std::float32_t, std::float64_t that use pre-existing
    _Arg_bf16, _Arg_f16, _Arg_f32, _Arg_f32 argument types.

    This does not affect formatting, as specialization of formatters for fixed
    width floating-point types formats them by casting to the corresponding
    standard floating point type.

    For the 128bit floating we need to handle the ppc64 architecture,
    (_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) for which the long double may (per TU
    basis) designate either __ibm128 and __ieee128 type, we need to store both
    types in the _Arg_value and have two _Arg_types (_Arg_ibm128,
_Arg_ieee128).
    On other architectures we use extra enumerator value to store __float128,
    that is different from long double and _Float128. This is consistent with
ppc64,
    for which __float128, if present, is same type as __ieee128. We use
_Arg_float128
    _M_float128 names that deviate from _Arg_fN naming scheme, to emphasize
that
    this flag is not used for std::float128_t (_Float128) type, that is
consistenly
    formatted via handle.

    The __format::__float128_t type is renamed to __format::__flt128_t, to
mitigate
    visual confusion between this type and __float128. We also introduce
__bflt16_t
    typedef instead of using of decltype.

    We add new alternative for the _Arg_value and allow them to be accessed via
_S_get,
    when the types are available. However, we produce and handle corresponding
_Arg_type,
    only when we can format them. See also r14-3329-g27d0cfcb2b33de.

    The formatter<_Float128, _CharT> that formats via __format::__flt128_t is
always
    provided, when type is available. It is still correct when
__format::__flt128_t
    is _Float128.

    We also provide formatter<__float128, _CharT> that formats via __flt128_t.
    As this type may be disabled (-mno-float128), extra care needs to be taken,
    for situation when __float128 is same as long double. If the formatter
would be
    defined in such case, the formatter<long double, _CharT> would be generated
    from different specializations, and have different mangling:
      * formatter<__float128, _CharT> if __float128 is present,
      * formatter<__format::__formattable_float, _CharT> otherwise.
    To best of my knowledge this happens only on ppc64 for __ieee128 and
__float128,
    so the formatter is not defined in this case. static_assert is added to
detect
    other configurations like that. In such case we should replace it with
constraint.

            PR libstdc++/119246

    libstdc++-v3/ChangeLog:

            * include/std/format (__format::__bflt16_t): Define.
            (_GLIBCXX_FORMAT_F128): Separate value for cases where _Float128
            is used.
            (__format::__float128_t): Renamed to __format::__flt128_t.
            (std::formatter<_Float128, _CharT>): Define always if there is
            formattable 128bit float.
            (std::formatter<__float128, _CharT>): Define.
            (_Arg_type::_Arg_f128): Rename to _Arg_float128 and adjust value.
            (_Arg_type::_Arg_ibm128): Change value to _Arg_ldbl.
            (_Arg_type::_Arg_ieee128): Define as alias to _Arg_float128.
            (_Arg_value::_M_f128): Replaced with _M_ieee128 and _M_float128.
            (_Arg_value::_M_ieee128, _Arg_value::_M_float128)
            (_Arg_value::_M_bf16, _Arg_value::_M_f16, _Arg_value::_M_f32)
            (_Arg_value::_M_f64): Define.
            (_Arg_value::_S_get, basic_format_arg::_S_to_enum): Handle
__bflt16,
            _Float16, _Float32, _Float64, and __float128 types.
            (basic_format_arg::_S_to_arg_type): Preserve _bflt16, _Float16,
            _Float32, _Float64 and __float128 types.
            (basic_format_arg::_M_visit): Handle _Arg_float128, _Arg_ieee128,
            _Arg_b16, _Arg_f16, _Arg_f32, _Arg_f64.
            * testsuite/std/format/arguments/args.cc: Updated to illustrate
            that extended floating point types use handles now. Added test
            for __float128.
            * testsuite/std/format/parse_ctx.cc: Extended test to cover class
            to check_dynamic_spec with floating point types and handles.

    Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
    Signed-off-by: Tomasz KamiÅski <tkami...@redhat.com>

Reply via email to