On 04/06/21 21:46 +0100, Jonathan Wakely wrote: >On 04/06/21 21:44 +0100, Jonathan Wakely wrote: >>On 04/06/21 18:03 +0100, Jonathan Wakely wrote: >>>The implementation of P2091R0 was incomplete, so that some range access >>>CPOs used perfect forwarding where they should not. This fixes it by >>>consistently operating on lvalues. >>> >>>Some additional changes that are not necessary to fix the bug: >>> >>>Modify the __as_const helper to simplify its usage. Instead of deducing >>>the value category from its argument, and requiring callers to forward >>>the argument as the correct category, add a non-deduced template >>>parameter which is used for the value category and accept the argument >>>as an lvalue. This means callers say __as_const(t) instead of >>>__as_const(std::forward(t)). >>> >>>Always use an lvalue reference type as the template argument for the >>>_S_noexcept helpers, so that we only instantiate one specialization for >>>lvalues and rvalues of the same type. >>> >>>Move some helper concepts and functions from namespace std::__detail >>>to ranges::__cust_access, to be consistent with the ranges::begin CPO. >>>This ensures that the __adl_begin concept and the _Begin::operator() >>>function are in the same namespace, so unqualified lookup is consistent >>>and the poison pills for begin are visible to both. >>> >>>Simplified static assertions for arrays, because the expression a+0 is >>>already ill-formed for an array of incomplete type. >>> >>>Signed-off-by: Jonathan Wakely >>> >>>libstdc++-v3/ChangeLog: >>> >>> PR libstdc++/100824 >>> * include/bits/iterator_concepts.h (__detail::__decay_copy) >>> (__detail::__member_begin, __detail::__adl_begin): Move to >>> namespace ranges::__cust_access. >>> (__detail::__ranges_begin): Likewise, and rename to __begin. >>> Remove redundant static assertion. >>> * include/bits/ranges_base.h (_Begin, _End, _RBegin, _REnd): >>> Use lvalue in noexcept specifier. >>> (__as_const): Add non-deduced parameter for value category. >>> (_CBegin, _CEnd, _CRBegin, _CREnd, _CData): Adjust uses of >>> __as_const. >>> (__member_size, __adl_size, __member_empty, __size0_empty): >>> (__eq_iter_empty, __adl_data): Use lvalue objects in >>> requirements. >>> (__sentinel_size): Likewise. Add check for conversion to >>> unsigned-like. >>> (__member_data): Allow non-lvalue types to satisfy the concept, >>> but use lvalue object in requirements. >>> (_Size, _SSize): Remove forwarding to always use an lvalue. >>> (_Data): Likewise. Add static assertion for arrays. >>> * testsuite/std/ranges/access/cdata.cc: Adjust expected >>> behaviour for rvalues. Add negative tests for ill-formed >>> expressions. >>> * testsuite/std/ranges/access/data.cc: Likewise. >>> * testsuite/std/ranges/access/empty.cc: Adjust expected >>> behaviour for rvalues. >>> * testsuite/std/ranges/access/size.cc: Likewise. >> >>An additional problem with ranges::data was pointed out in the PR, >>fixed with this patch. > >And this implements the rest of LWG 3403. The change to the >ranges::ssize constraints was already done by the first patch in this >thread, this fixes the return type. Aaaaand one more fix, as pointed out in the PR. Tested x86_64-linux. Committed to trunk. And this one should also be backported to gcc-11 and gcc-10.