On Wed, 14 May 2025 at 20:50, Iain Sandoe <idsan...@googlemail.com> wrote: > > > > > 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.
Tomasz, should this be: --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -2973,7 +2973,7 @@ namespace __format }; #endif -#if defined(__SIZEOF_FLOAT128__) && _GLIBCXX_FORMAT_F128 != 1 +#if defined(__SIZEOF_FLOAT128__) && _GLIBCXX_FORMAT_F128 > 1 // Reuse __formatter_fp<C>::format<__format::__flt128_t, Out> for __float128. // This formatter is not declared if _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT is true, // as __float128 when present is same type as __ieee128, which may be same as > > Iain > > > > > Rainer > > > > -- > > ----------------------------------------------------------------------------- > > Rainer Orth, Center for Biotechnology, Bielefeld University >