From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2136) id 80DA03938C00; Wed, 17 Jun 2020 19:02:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80DA03938C00 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1592420526; bh=fWyrUnZLLqRGFOMCVJjVWK85/1WGITVoAGghaValaS8=; h=From:To:Subject:Date:From; b=alsIfwbAwmWpstpgyKKdIRzBOcUVmSsz1JxG/4X49tiwt4CtOvXa9q8gwhSb1lSP/ ep7xmff5HqeixeM/8IC/tOMyEb+gBJB6cKqJTrgZhVhn3CS5r26e8HBd+vlEdIsrjE AIl8d3pKkM4iohxPhpOwo9+CieF5IuhLWUFyPUsE= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Aldy Hernandez To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/ranger] libstdc++: subrange converting constructor should disallow slicing (LWG 3282) X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/devel/ranger X-Git-Oldrev: 59aa9e577eb2b182374f5421828687c93b81ad3d X-Git-Newrev: 77f5310f0205714538668b88fbf1de44f1f435be Message-Id: <20200617190206.80DA03938C00@sourceware.org> Date: Wed, 17 Jun 2020 19:02:06 +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: Wed, 17 Jun 2020 19:02:06 -0000 https://gcc.gnu.org/g:77f5310f0205714538668b88fbf1de44f1f435be commit 77f5310f0205714538668b88fbf1de44f1f435be Author: Jonathan Wakely 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: --- libstdc++-v3/ChangeLog | 9 ++++ libstdc++-v3/include/std/ranges | 48 ++++++++-------------- .../testsuite/std/ranges/subrange/lwg3282_neg.cc | 31 ++++++++++++++ 3 files changed, 57 insertions(+), 31 deletions(-) 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 + * 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 + concept __convertible_to_non_slicing = convertible_to<_From, _To> + && !(is_pointer_v> && is_pointer_v> + && __not_same_as>, + remove_pointer_t>>); + template concept __pair_like = !is_reference_v<_Tp> && requires(_Tp __t) @@ -226,19 +232,12 @@ namespace ranges { get<1>(__t) } -> convertible_to&>; }; - template - concept __pair_like_convertible_to - = !range<_Tp> && __pair_like> - && requires(_Tp&& __t) - { - { get<0>(std::forward<_Tp>(__t)) } -> convertible_to<_Up>; - { get<1>(std::forward<_Tp>(__t)) } -> convertible_to<_Vp>; - }; - template 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 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> __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 _Rng> requires borrowed_range<_Rng> - && convertible_to, _It> + && __detail::__convertible_to_non_slicing, _It> && convertible_to, _Sent> constexpr subrange(_Rng&& __r) requires (!_S_store_size || sized_range<_Rng>) @@ -306,7 +306,7 @@ namespace ranges } template - requires convertible_to, _It> + requires __detail::__convertible_to_non_slicing, _It> && convertible_to, _Sent> constexpr subrange(_Rng&& __r, @@ -315,23 +315,6 @@ namespace ranges : subrange{ranges::begin(__r), ranges::end(__r), __n} { } - template<__detail::__not_same_as _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> __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 _PairLike> requires __detail::__pair_like_convertible_from<_PairLike, const _It&, const _Sent&> @@ -402,6 +385,9 @@ namespace ranges } }; + template _Sent> + subrange(_It, _Sent) -> subrange<_It, _Sent>; + template _Sent> subrange(_It, _Sent, __detail::__make_unsigned_like_t>) 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +using std::ranges::subrange; + +// LWG 3282. subrange converting constructor should disallow derived to base +// conversions + +struct Base {}; +struct Derived : Base {}; +subrange sd; +subrange sb = sd; // { dg-error "conversion" }