> On 14 May 2025, at 18:42, Rainer Orth <r...@cebitec.uni-bielefeld.de> wrote:
>
> Hi Jonathan,
>
>> On 14/05/25 10:01 +0200, Tomasz Kamiński wrote:
>>> 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.
>>> ---
>>> I believe I have fixed all the typos. OK for trunk?
>>
>>
>> OK, thanks
>
> this patch broke Solaris bootstrap, both i386-pc-solaris2.11 and
> sparc-sun-solaris2.11:
>
> In file included from
> /vol/gcc/src/hg/master/local/libstdc++-v3/src/c++20/format.cc:29:
> /var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/format:
> In member function ‘typename std::basic_format_context<_Out,
> _CharT>::iterator std::formatter<__float128, _CharT>::format(__float128,
> std::basic_format_context<_Out, _CharT>&) const’:
> /var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/format:2994:41:
> error: ‘__flt128_t’ is not a member of ‘std::__format’; did you mean
> ‘__bflt16_t’? [-Wtemplate-body]
> 2994 | { return _M_f.format((__format::__flt128_t)__u, __fc); }
> | ^~~~~~~~~~
> | __bflt16_t
>
> and one more instance.
And on x86_64-darwin too.
Iain
>
> Rainer
>
> --
> -----------------------------------------------------------------------------
> Rainer Orth, Center for Biotechnology, Bielefeld University