public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/ranger] libstdc++: Issues with range access CPOs (P2091R0) Date: Wed, 17 Jun 2020 19:03:38 +0000 (GMT) [thread overview] Message-ID: <20200617190338.4125D3939C15@sourceware.org> (raw) https://gcc.gnu.org/g:e817c23f6806a6b9201a0a1f77b51cb863af51e9 commit e817c23f6806a6b9201a0a1f77b51cb863af51e9 Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Feb 20 13:20:44 2020 +0000 libstdc++: Issues with range access CPOs (P2091R0) This changes how arrays of unknown bound and/or incomplete element type are handled. * include/bits/range_access.h (ranges::begin): Reject array of incomplete type. (ranges::end, ranges::size): Require arrays to be bounded. (ranges::data): Require lvalue or borrowed_range. (ranges::iterator_t): Remove constraint. * testsuite/std/ranges/access/begin.cc: Do not check array of incomplete type. * testsuite/std/ranges/access/begin_neg.cc: New test. * testsuite/std/ranges/access/end_neg.cc: Adjust expected error. * testsuite/std/ranges/access/size_neg.cc: Adjust expected error. * testsuite/std/ranges/access/ssize.cc: Do not check array of incomplete type. Diff: --- libstdc++-v3/ChangeLog | 13 +++++++ libstdc++-v3/include/bits/range_access.h | 42 ++++++++++++---------- libstdc++-v3/testsuite/std/ranges/access/begin.cc | 6 ++-- .../testsuite/std/ranges/access/begin_neg.cc | 39 ++++++++++++++++++++ .../testsuite/std/ranges/access/end_neg.cc | 5 +-- .../testsuite/std/ranges/access/size_neg.cc | 3 +- libstdc++-v3/testsuite/std/ranges/access/ssize.cc | 5 --- 7 files changed, 80 insertions(+), 33 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b4b95dfc5e7..30cf706cdae 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,18 @@ 2020-02-20 Jonathan Wakely <jwakely@redhat.com> + * include/bits/range_access.h (ranges::begin): Reject array of + incomplete type. + (ranges::end, ranges::size): Require arrays to be bounded. + (ranges::data): Require lvalue or borrowed_range. + (ranges::iterator_t): Remove constraint. + * testsuite/std/ranges/access/begin.cc: Do not check array of + incomplete type. + * testsuite/std/ranges/access/begin_neg.cc: New test. + * testsuite/std/ranges/access/end_neg.cc: Adjust expected error. + * testsuite/std/ranges/access/size_neg.cc: Adjust expected error. + * testsuite/std/ranges/access/ssize.cc: Do not check array of + incomplete type. + * include/std/system_error (error_category::operator<=>) (operator<=>(const error_code&, const error_code&)) (operator<=>(const error_condition&, const error_condition&)): Define diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h index e7a19305d23..eb91ade35ff 100644 --- a/libstdc++-v3/include/bits/range_access.h +++ b/libstdc++-v3/include/bits/range_access.h @@ -382,8 +382,8 @@ namespace ranges { __decay_copy(__t.begin()) } -> input_or_output_iterator; }; - template<typename _Tp> void begin(_Tp&&) = delete; - template<typename _Tp> void begin(initializer_list<_Tp>&&) = delete; + void begin(auto&) = delete; + void begin(const auto&) = delete; template<typename _Tp> concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>> @@ -417,7 +417,9 @@ namespace ranges if constexpr (is_array_v<remove_reference_t<_Tp>>) { static_assert(is_lvalue_reference_v<_Tp>); - return __t; + using _Up = remove_all_extents_t<remove_reference_t<_Tp>>; + static_assert(sizeof(_Up) != 0, "not array of incomplete type"); + return __t + 0; } else if constexpr (__member_begin<_Tp>) return __t.begin(); @@ -433,8 +435,8 @@ namespace ranges -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>; }; - template<typename _Tp> void end(_Tp&&) = delete; - template<typename _Tp> void end(initializer_list<_Tp>&&) = delete; + void end(auto&) = delete; + void end(const auto&) = delete; template<typename _Tp> concept __adl_end = __class_or_enum<remove_reference_t<_Tp>> @@ -451,7 +453,7 @@ namespace ranges static constexpr bool _S_noexcept() { - if constexpr (is_array_v<remove_reference_t<_Tp>>) + if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>) return true; else if constexpr (__member_end<_Tp>) return noexcept(__decay_copy(std::declval<_Tp&>().end())); @@ -461,15 +463,14 @@ namespace ranges public: template<__maybe_borrowed_range _Tp> - requires is_array_v<remove_reference_t<_Tp>> || __member_end<_Tp> + requires is_bounded_array_v<remove_reference_t<_Tp>> || __member_end<_Tp> || __adl_end<_Tp> constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>()) { - if constexpr (is_array_v<remove_reference_t<_Tp>>) + if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>) { static_assert(is_lvalue_reference_v<_Tp>); - static_assert(is_bounded_array_v<remove_reference_t<_Tp>>); return __t + extent_v<remove_reference_t<_Tp>>; } else if constexpr (__member_end<_Tp>) @@ -519,7 +520,8 @@ namespace ranges { __decay_copy(__t.rbegin()) } -> input_or_output_iterator; }; - template<typename _Tp> void rbegin(_Tp&&) = delete; + void rbegin(auto&) = delete; + void rbegin(const auto&) = delete; template<typename _Tp> concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>> @@ -582,7 +584,8 @@ namespace ranges -> sentinel_for<decltype(_RBegin{}(__t))>; }; - template<typename _Tp> void rend(_Tp&&) = delete; + void rend(auto&) = delete; + void rend(const auto&) = delete; template<typename _Tp> concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>> @@ -664,7 +667,8 @@ namespace ranges -> __detail::__is_integer_like; }; - template<typename _Tp> void size(_Tp&&) = delete; + void size(auto&) = delete; + void size(const auto&) = delete; template<typename _Tp> concept __adl_size = __class_or_enum<remove_reference_t<_Tp>> @@ -691,7 +695,7 @@ namespace ranges static constexpr bool _S_noexcept() { - if constexpr (is_array_v<remove_reference_t<_Tp>>) + if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>) return true; else if constexpr (__member_size<_Tp>) return noexcept(__decay_copy(std::declval<_Tp>().size())); @@ -704,14 +708,13 @@ namespace ranges public: template<typename _Tp> - requires is_array_v<remove_reference_t<_Tp>> + requires is_bounded_array_v<remove_reference_t<_Tp>> || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp> constexpr auto operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>()) { - if constexpr (is_array_v<remove_reference_t<_Tp>>) + if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>) { - static_assert(is_bounded_array_v<remove_reference_t<_Tp>>); return extent_v<remove_reference_t<_Tp>>; } else if constexpr (__member_size<_Tp>) @@ -826,7 +829,8 @@ namespace ranges } public: - template<typename _Tp> requires __member_data<_Tp> || __begin_data<_Tp> + template<__maybe_borrowed_range _Tp> + requires __member_data<_Tp> || __begin_data<_Tp> constexpr auto operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>()) { @@ -881,8 +885,8 @@ namespace ranges concept borrowed_range = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>; - template<range _Range> - using iterator_t = decltype(ranges::begin(std::declval<_Range&>())); + template<typename _Tp> + using iterator_t = decltype(ranges::begin(std::declval<_Tp&>())); template<range _Range> using sentinel_t = decltype(ranges::end(std::declval<_Range&>())); diff --git a/libstdc++-v3/testsuite/std/ranges/access/begin.cc b/libstdc++-v3/testsuite/std/ranges/access/begin.cc index b6801552c60..9cbdfe25a22 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/begin.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/begin.cc @@ -36,10 +36,10 @@ test01() constexpr long b[2] = { }; static_assert( std::ranges::begin(b) == (b + 0) ); - struct Incomplete; - using A = Incomplete[]; // unbounded array of incomplete type + struct X { }; + using A = X[]; // unbounded array extern A& f(); - static_assert( same_as<decltype(std::ranges::begin(f())), Incomplete*> ); + static_assert( same_as<decltype(std::ranges::begin(f())), X*> ); } void diff --git a/libstdc++-v3/testsuite/std/ranges/access/begin_neg.cc b/libstdc++-v3/testsuite/std/ranges/access/begin_neg.cc new file mode 100644 index 00000000000..f31428526f3 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/access/begin_neg.cc @@ -0,0 +1,39 @@ +// 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> + +auto +test01() +{ + using A = int[2]; + extern A&& f(); // rvalue of type that doesn't satisfy borrowed_range + return std::ranges::begin(f()); // { dg-error "no match" } +} + +struct incomplete; +extern incomplete array[2]; + +auto +test02() +{ + return std::ranges::begin(array); // { dg-error "here" } +} +// { dg-error "incomplete type" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc b/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc index 3f690faa73d..e16f684443e 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc @@ -25,9 +25,8 @@ extern int unbounded[]; auto test01() { - return std::ranges::end(unbounded); // { dg-error "here" } + return std::ranges::end(unbounded); // { dg-error "no match" } } -// { dg-error "static assertion failed" "" { target *-*-* } 0 } struct incomplete; extern incomplete array[2]; @@ -38,5 +37,3 @@ test02() return std::ranges::end(array); // { dg-error "here" } } // { dg-error "incomplete type" "" { target *-*-* } 0 } - - diff --git a/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc b/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc index 6ff8c1f892a..10d9b141fbf 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc @@ -25,6 +25,5 @@ extern int unbounded[]; auto test01() { - return std::ranges::size(unbounded); // { dg-error "here" } + return std::ranges::size(unbounded); // { dg-error "no match" } } -// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/std/ranges/access/ssize.cc b/libstdc++-v3/testsuite/std/ranges/access/ssize.cc index 5aa05be8f20..6f5478e2bb1 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/ssize.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/ssize.cc @@ -36,11 +36,6 @@ test01() static_assert( std::same_as<decltype(std::ranges::ssize(a2)), ptrdiff_t> ); VERIFY( std::ranges::ssize(a2) == 2); static_assert( noexcept(std::ranges::ssize(a2)) ); - - struct Incomplete; - using A = Incomplete[2]; // bounded array of incomplete type - extern A& f(); - static_assert( std::same_as<decltype(std::ranges::ssize(f())), ptrdiff_t> ); } void
reply other threads:[~2020-06-17 19:03 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200617190338.4125D3939C15@sourceware.org \ --to=aldyh@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).