On Sat, 14 Oct 2023, 00:33 Benjamin Brock, wrote: > This is my first time submitting a patch, so my apologies if I'm > submitting incorrectly or missing something. > Thanks for contributing! I don't think this patch counts as legally significant, but if you contribute again in future you should be aware of https://gcc.gnu.org/contribute.html#legal and either complete the copyright assignment paperwork, or add a DCO sign-off to the commit message. > Clang is unable to compile parts of libstdc++'s ranges implementation > due to LLVM-61763, a Clang frontend compiler bug in handling the > declarations of constrained friends. The problem areas are zip_view, > zip_transform_view, and adjacent_transform_view. > > A simple ranges program like the following fails to compile using > Clang trunk and libstdc++. > > std::vector v = {1, 2, 3, 4}; > int sum = 0; > for (auto&& [i, j] : std::ranges::views::zip(v, v)) > sum += i * j; > > In file included from :1: > > /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/ranges:4655:14: > error: type constraint differs in template redeclaration > 4655 | template > | ^ > . . . . . . > > Godbolt: https://godbolt.org/z/Ynbs15aGh > > This patch adds a small workaround that avoids declaring constrained > friends when compiling with Clang, instead making some members public. > MSVC's standard library has implemented a similar workaround. > > Scanning through libstdc++, there do appear to be other workarounds > for Clang, e.g. in complex and experimental/simd. Hopefully this kind > of workaround is acceptable---while the core issue is a Clang compiler > bug, it may take a while to fix, and it would be very useful for > libstdc++ ranges to work with Clang in the meantime. > Yes, this is ok because the hack is limited to __clang__. > 2023-10-13 Benjamin Brock > > libstdc++-v3/ChangeLog: > > * include/std/ranges: implement workaround for LLVM-61763 in > zip_view and adjacency_view > This should be a complete sentence, so capital letter and full stop. I can get this pushed to trunk and gcc-13 next week, thanks again for the patch. > --- > > diff --git a/libstdc++-v3/include/std/ranges > b/libstdc++-v3/include/std/ranges > index 1d529a886be..7893e3a84c9 100644 > --- a/libstdc++-v3/include/std/ranges > +++ b/libstdc++-v3/include/std/ranges > @@ -4632,6 +4632,9 @@ namespace views::__adaptor > class zip_view<_Vs...>::_Iterator > : public __detail::__zip_view_iter_cat<_Const, _Vs...> > { > +#ifdef __clang__ // LLVM-61763 workaround > + public: > +#endif > > __detail::__tuple_or_pair_t _Vs>>...> _M_current; > > constexpr explicit > @@ -4652,11 +4655,13 @@ namespace views::__adaptor > return input_iterator_tag{}; > } > > +#ifndef __clang__ // LLVM-61763 workaround > template > requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && > is_object_v<_Fp> > && regular_invocable<_Fp&, range_reference_t<_Ws>...> > && std::__detail::__can_reference range_reference_t<_Ws>...>> > friend class zip_transform_view; > +#endif > > public: > // iterator_category defined in __zip_view_iter_cat > @@ -5327,6 +5332,9 @@ namespace views::__adaptor > template > class adjacent_view<_Vp, _Nm>::_Iterator > { > +#ifdef __clang__ // LLVM-61763 workaround > + public: > +#endif > using _Base = __detail::__maybe_const_t<_Const, _Vp>; > array, _Nm> _M_current = array, > _Nm>(); > > @@ -5367,12 +5375,14 @@ namespace views::__adaptor > > friend class adjacent_view; > > +#ifndef __clang__ // LLVM-61763 workaround > template > requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp> > && regular_invocable<__detail::__unarize<_Fp&, _Mm>, > range_reference_t<_Wp>> > && > std::__detail::__can_reference _Mm>, > > range_reference_t<_Wp>>> > friend class adjacent_transform_view; > +#endif > > public: > using iterator_category = input_iterator_tag; >