On Mon, 31 Oct 2022 at 16:57, Jakub Jelinek <ja...@redhat.com> wrote: > > On Mon, Oct 31, 2022 at 10:26:11AM +0000, Jonathan Wakely wrote: > > > --- libstdc++-v3/include/std/complex.jj 2022-10-21 08:55:43.037675332 > > > +0200 > > > +++ libstdc++-v3/include/std/complex 2022-10-21 17:05:36.802243229 > > > +0200 > > > @@ -142,8 +142,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > > > > /// Converting constructor. > > > template<typename _Up> > > > +#if __cplusplus > 202002L > > > + explicit(!requires(_Up __u) { _Tp{__u}; }) > > > + constexpr complex(const complex<_Up>& __z) > > > + : _M_real(_Tp(__z.real())), _M_imag(_Tp(__z.imag())) { } > > > > Do these casts to _Tp do anything? The _M_real and _M_imag members are > > already of type _Tp and we're using () initialization not {} so > > there's no narrowing concern. _M_real(__z.real()) is already an > > explicit conversion from decltype(__z.real()) to decltype(_M_real) so > > the extra _Tp is redundant. > > If I use just > : _M_real(__z.real()), _M_imag(__z.imag()) { } > then without -Wsystem-headers there are no regressions, but compiling > g++.dg/cpp23/ext-floating12.C with additional -Wsystem-headers > -pedantic-errors results in lots of extra errors on that line: > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float32’ from ‘double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float32’ from ‘double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float32’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float32’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float32’ from ‘_Float64’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float32’ from ‘_Float64’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float32’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float32’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float64’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float64’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float64’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float64’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘float’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘float’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘_Float32’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘_Float32’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘_Float64’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘_Float64’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘_Float16’ from ‘__bf16’ with unordered conversion ranks > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘_Float16’ from ‘__bf16’ with unordered conversion ranks > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘float’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘float’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘long double’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘_Float32’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘_Float32’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘_Float64’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘_Float64’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘_Float128’ with greater conversion rank > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:27: error: > converting to ‘__bf16’ from ‘_Float16’ with unordered conversion ranks > .../x86_64-pc-linux-gnu/libstdc++-v3/include/complex:149:48: error: > converting to ‘__bf16’ from ‘_Float16’ with unordered conversion ranks > > __z doesn't have _Tp type, but _Up, which is some other floating
Right. > point type. For the conversion constructors where we have > explicit(false) all is fine, we've tested in the requires that > _Up is implicitly convertable to _Tp. > But if explicit(true), it is fine without the explicit casts only > for long double -> float, long double -> double and double -> float > casts which are ok for implicit casts but not in narrowing conversions > with non-constants. > Otherwise it results in the above diagnostics. That seems like a compiler bug. I don't see any reason for val(x) to be different from val(T(x)) when T is decltype(val). They are both direct-initialization of T from x. > > > I think the diff between C++23 and older standards would be smaller > > done like this: > > > > /// Converting constructor. > > template<typename _Up> > > #if __cplusplus > 202002L > > explicit(!requires(_Up __u) { _Tp{__u}; }) > > #endif > > _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z) > > : _M_real(__z.real()), _M_imag(__z.imag()) { } > > I could go for this with the _Tp() casts everywhere, or > make also that line (perhaps except for { }) also conditional on > #if __cplusplus > 202002L. > > > This also means the constructor body is always defined on the same > > line, which avoids warnings from ld.gold's -Wodr-violations which IIRC > > is based on simple heuristics like the line where the function is > > defined. > > > > Otherwise this looks great. If the above alternative works, please use > > that, but OK for trunk either way (once all the other patches it > > depends on are in). > > All the builtins patches are in since today, and the > "Small extended float support tweaks" patch is in too (it had a small > testsuite conflict due to the > https://gcc.gnu.org/pipermail/libstdc++/2022-October/054849.html > patch still pending, but I've just resolved that conflict). > I think this patch doesn't depend on anything anymore. > > OT, I also get on the same testcase with -Wsystem-headers -pedantic-errors > .../x86_64-pc-linux-gnu/libstdc++-v3/include/cmath:47:2: error: #include_next > is a GCC extension > .../x86_64-pc-linux-gnu/libstdc++-v3/include/bits/std_abs.h:38:2: error: > #include_next is a GCC extension > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/numbers:223:1: error: > non-standard suffix on floating constant [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/cstdlib:79:2: error: > #include_next is a GCC extension > .../libstdc++-v3/libsupc++/compare:844:45: error: ISO C++ does not support > ‘__int128’ for ‘type name’ [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/cstddef:91:36: error: ISO C++ > does not support ‘__int128’ for ‘type name’ [-Wpedantic] > .../x86_64-pc-linux-gnu/libstdc++-v3/include/cstddef:93:45: error: ISO C++ > does not support ‘__int128’ for ‘type name’ [-Wpedantic] > For the numbers case (__float128 in there), wonder if we can wrap it in > __extension__ or > use __extension__ __float128 as the type (apparently e.g. type_traits uses > __extension__ before the template keyword of the specializations), for the > __int128 cases perhaps > too, no idea about #include_next though. Yeah, __extension__ works in some places, although I think I've found places it doesn't help. The #include_next one has no way to disable it, which is annoying.