From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id A9C2D384782B; Thu, 10 Jun 2021 21:22:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A9C2D384782B MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r10-9908] libstdc++: Avoid hard error in ranges::unique_copy [PR100770] X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/releases/gcc-10 X-Git-Oldrev: 8f5cda0e646822bbd01e642ed28a4f4f0cca8c59 X-Git-Newrev: bee80d74f7ebc8e1ada913aa059dedc0976f28c0 Message-Id: <20210610212249.A9C2D384782B@sourceware.org> Date: Thu, 10 Jun 2021 21:22:49 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Jun 2021 21:22:49 -0000 https://gcc.gnu.org/g:bee80d74f7ebc8e1ada913aa059dedc0976f28c0 commit r10-9908-gbee80d74f7ebc8e1ada913aa059dedc0976f28c0 Author: Patrick Palka Date: Thu Jun 3 12:30:29 2021 -0400 libstdc++: Avoid hard error in ranges::unique_copy [PR100770] Here, in the constexpr if condition within ranges::unique_copy, when input_iterator<_Out> isn't satisfied we must avoid substituting into iter_value_t<_Out> because the latter isn't necessarily well-formed then. To that end, this patch factors out the condition into a concept and uses it throughout. This patch also makes the definition of our testsuite output_iterator_wrapper more minimal by setting its value_type, pointer and reference member types to void. This means our existing tests for unique_copy already exercise the fix for this bug, so we don't need to add another test. The only other fallout of this testsuite iterator change appears in std/ranges/range.cc, where the use of range_value_t on a test_output_range is now ill-formed. PR libstdc++/100770 libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h (__detail::__can_reread_output): Factor out this concept from ... (__unique_copy_fn::operator()): ... here. Use the concept throughout. * testsuite/std/ranges/range.cc: Remove now ill-formed use of range_value_t on an output_range. * testsuite/util/testsuite_iterators.h (output_iterator_wrapper): Define value_type, pointer and reference member types to void. (cherry picked from commit 0614bbbe59c6953e088cffa39dfe63d86fc1fa96) Diff: --- libstdc++-v3/include/bits/ranges_algo.h | 16 ++++++++++------ libstdc++-v3/testsuite/std/ranges/range.cc | 3 --- libstdc++-v3/testsuite/util/testsuite_iterators.h | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 095730974cd..92ab045aa6a 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -1395,6 +1395,13 @@ namespace ranges inline constexpr __unique_fn unique{}; + namespace __detail + { + template + concept __can_reread_output = input_iterator<_Out> + && same_as<_Tp, iter_value_t<_Out>>; + } + template using unique_copy_result = in_out_result<_Iter, _Out>; @@ -1406,8 +1413,7 @@ namespace ranges projected<_Iter, _Proj>> _Comp = ranges::equal_to> requires indirectly_copyable<_Iter, _Out> && (forward_iterator<_Iter> - || (input_iterator<_Out> - && same_as, iter_value_t<_Out>>) + || __detail::__can_reread_output<_Out, iter_value_t<_Iter>> || indirectly_copyable_storable<_Iter, _Out>) constexpr unique_copy_result<_Iter, _Out> operator()(_Iter __first, _Sent __last, _Out __result, @@ -1431,8 +1437,7 @@ namespace ranges } return {__next, std::move(++__result)}; } - else if constexpr (input_iterator<_Out> - && same_as, iter_value_t<_Out>>) + else if constexpr (__detail::__can_reread_output<_Out, iter_value_t<_Iter>>) { *__result = *__first; while (++__first != __last) @@ -1466,8 +1471,7 @@ namespace ranges projected, _Proj>> _Comp = ranges::equal_to> requires indirectly_copyable, _Out> && (forward_iterator> - || (input_iterator<_Out> - && same_as, iter_value_t<_Out>>) + || __detail::__can_reread_output<_Out, range_value_t<_Range>> || indirectly_copyable_storable, _Out>) constexpr unique_copy_result, _Out> operator()(_Range&& __r, _Out __result, diff --git a/libstdc++-v3/testsuite/std/ranges/range.cc b/libstdc++-v3/testsuite/std/ranges/range.cc index cf349de8735..5548e93d6cd 100644 --- a/libstdc++-v3/testsuite/std/ranges/range.cc +++ b/libstdc++-v3/testsuite/std/ranges/range.cc @@ -75,9 +75,6 @@ static_assert( same_as, static_assert( same_as, std::ptrdiff_t> ); -static_assert( same_as, - char> ); - static_assert( same_as, char&> ); static_assert( same_as, diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index 60eba26eab4..8c4b8b7c6cc 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -122,7 +122,7 @@ namespace __gnu_test */ template struct output_iterator_wrapper - : public std::iterator + : public std::iterator { protected: output_iterator_wrapper() : ptr(0), SharedInfo(0)