subrange converting constructor should disallow slicing (LWG 3282) ranges::iter_move should perform ADL-only lookup (LWG 3247)
Tested powerpc64le-linux, committed to master.
commit 77f5310f0205714538668b88fbf1de44f1f435be Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Feb 19 17:04:07 2020 +0000 libstdc++: subrange converting constructor should disallow slicing (LWG 3282) * include/std/ranges (__detail::__convertible_to_non_slicing): New helper concept. (__detail::__pair_like_convertible_to): Remove. (__detail::__pair_like_convertible_from): Add requirements for non-slicing conversions. (subrange): Constrain constructors with __convertible_to_non_slicing. Remove constructors from pair-like types. Add new deduction guide. * testsuite/std/ranges/subrange/lwg3282_neg.cc: New test. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 689bee8c2a9..6e22536680f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2020-02-19 Jonathan Wakely <jwak...@redhat.com> + * include/std/ranges (__detail::__convertible_to_non_slicing): New + helper concept. + (__detail::__pair_like_convertible_to): Remove. + (__detail::__pair_like_convertible_from): Add requirements for + non-slicing conversions. + (subrange): Constrain constructors with __convertible_to_non_slicing. + Remove constructors from pair-like types. Add new deduction guide. + * testsuite/std/ranges/subrange/lwg3282_neg.cc: New test. + * include/bits/iterator_concepts.h (iter_move): Add declaration to prevent unqualified lookup finding a suitable declaration (LWG 3247). diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index b0806750a08..b348ba2cfcb 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -214,6 +214,12 @@ namespace ranges namespace __detail { + template<class _From, class _To> + concept __convertible_to_non_slicing = convertible_to<_From, _To> + && !(is_pointer_v<decay_t<_From>> && is_pointer_v<decay_t<_To>> + && __not_same_as<remove_pointer_t<decay_t<_From>>, + remove_pointer_t<decay_t<_To>>>); + template<typename _Tp> concept __pair_like = !is_reference_v<_Tp> && requires(_Tp __t) @@ -226,19 +232,12 @@ namespace ranges { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>; }; - template<typename _Tp, typename _Up, typename _Vp> - concept __pair_like_convertible_to - = !range<_Tp> && __pair_like<remove_reference_t<_Tp>> - && requires(_Tp&& __t) - { - { get<0>(std::forward<_Tp>(__t)) } -> convertible_to<_Up>; - { get<1>(std::forward<_Tp>(__t)) } -> convertible_to<_Vp>; - }; - template<typename _Tp, typename _Up, typename _Vp> concept __pair_like_convertible_from = !range<_Tp> && __pair_like<_Tp> - && constructible_from<_Tp, _Up, _Vp>; + && constructible_from<_Tp, _Up, _Vp> + && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>> + && convertible_to<_Vp, tuple_element_t<1, _Tp>>; template<typename _Tp> concept __iterator_sentinel_pair @@ -277,12 +276,13 @@ namespace ranges subrange() = default; constexpr - subrange(_It __i, _Sent __s) requires (!_S_store_size) + subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s) + requires (!_S_store_size) : _M_begin(std::move(__i)), _M_end(__s) { } constexpr - subrange(_It __i, _Sent __s, + subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s, __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n) requires (_Kind == subrange_kind::sized) : _M_begin(std::move(__i)), _M_end(__s) @@ -295,7 +295,7 @@ namespace ranges template<__detail::__not_same_as<subrange> _Rng> requires borrowed_range<_Rng> - && convertible_to<iterator_t<_Rng>, _It> + && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It> && convertible_to<sentinel_t<_Rng>, _Sent> constexpr subrange(_Rng&& __r) requires (!_S_store_size || sized_range<_Rng>) @@ -306,7 +306,7 @@ namespace ranges } template<borrowed_range _Rng> - requires convertible_to<iterator_t<_Rng>, _It> + requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It> && convertible_to<sentinel_t<_Rng>, _Sent> constexpr subrange(_Rng&& __r, @@ -315,23 +315,6 @@ namespace ranges : subrange{ranges::begin(__r), ranges::end(__r), __n} { } - template<__detail::__not_same_as<subrange> _PairLike> - requires __detail::__pair_like_convertible_to<_PairLike, _It, _Sent> - constexpr - subrange(_PairLike&& __r) requires (!_S_store_size) - : subrange{std::get<0>(std::forward<_PairLike>(__r)), - std::get<1>(std::forward<_PairLike>(__r))} - { } - - template<__detail::__pair_like_convertible_to<_It, _Sent> _PairLike> - constexpr - subrange(_PairLike&& __r, - __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n) - requires (_Kind == subrange_kind::sized) - : subrange{std::get<0>(std::forward<_PairLike>(__r)), - std::get<1>(std::forward<_PairLike>(__r)), __n} - { } - template<__detail::__not_same_as<subrange> _PairLike> requires __detail::__pair_like_convertible_from<_PairLike, const _It&, const _Sent&> @@ -402,6 +385,9 @@ namespace ranges } }; + template<input_or_output_iterator _It, sentinel_for<_It> _Sent> + subrange(_It, _Sent) -> subrange<_It, _Sent>; + template<input_or_output_iterator _It, sentinel_for<_It> _Sent> subrange(_It, _Sent, __detail::__make_unsigned_like_t<iter_difference_t<_It>>) diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/lwg3282_neg.cc b/libstdc++-v3/testsuite/std/ranges/subrange/lwg3282_neg.cc new file mode 100644 index 00000000000..5c2f1de45ad --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/subrange/lwg3282_neg.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <ranges> + +using std::ranges::subrange; + +// LWG 3282. subrange converting constructor should disallow derived to base +// conversions + +struct Base {}; +struct Derived : Base {}; +subrange<Derived*> sd; +subrange<Base*> sb = sd; // { dg-error "conversion" } commit 59aa9e577eb2b182374f5421828687c93b81ad3d Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Feb 19 16:43:07 2020 +0000 libstdc++: ranges::iter_move should perform ADL-only lookup (LWG 3247) * include/bits/iterator_concepts.h (iter_move): Add declaration to prevent unqualified lookup finding a suitable declaration (LWG 3247). diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 067cf8343f6..689bee8c2a9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,8 @@ 2020-02-19 Jonathan Wakely <jwak...@redhat.com> + * include/bits/iterator_concepts.h (iter_move): Add declaration to + prevent unqualified lookup finding a suitable declaration (LWG 3247). + * include/std/memory_resource (polymorphic_allocator::allocate) (polymorphic_allocator::allocate_object): Change type of exception to bad_array_new_length (LWG 3237). diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index 792b3262106..08e622259b4 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -79,6 +79,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { namespace __cust_imove { + void iter_move(); + template<typename _Tp> concept __adl_imove = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>)