From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id D9D313AA7C92 for ; Thu, 5 Aug 2021 14:19:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D9D313AA7C92 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-359-Ex4A7NZUMUqytyp8Rr4sGw-1; Thu, 05 Aug 2021 10:19:05 -0400 X-MC-Unique: Ex4A7NZUMUqytyp8Rr4sGw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 711F58799F6; Thu, 5 Aug 2021 14:19:04 +0000 (UTC) Received: from localhost (unknown [10.33.36.118]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC04626379; Thu, 5 Aug 2021 14:19:03 +0000 (UTC) Date: Thu, 5 Aug 2021 15:19:03 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Move attributes that follow requires-clauses [PR101782] Message-ID: References: MIME-Version: 1.0 In-Reply-To: X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="9kPyG2yHaXB6Fy/O" Content-Disposition: inline X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, URI_HEX autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Aug 2021 14:19:10 -0000 --9kPyG2yHaXB6Fy/O Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline On 04/08/21 12:55 +0100, Jonathan Wakely wrote: >This adds [[nodiscard]] throughout , as proposed by P2377R0 >(with some minor corrections). > >The attribute is added for all modes from C++11 up, using >[[__nodiscard__]] or _GLIBCXX_NODISCARD where C++17 [[nodiscard]] can't >be used directly. This change causes errors when -fconcepts-ts is used. Fixed like so. Tested powerpc64le-linux, committed to trunk. --9kPyG2yHaXB6Fy/O Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 7b1de3eb9ed3f8dde54732d88520292c5ad1157d Author: Jonathan Wakely Date: Thu Aug 5 13:34:00 2021 libstdc++: Move attributes that follow requires-clauses [PR101782] As explained in the PR, the grammar in the Concepts TS means that a [ token following a requires-clause is parsed as part of the logical-or-expression rather than the start of an attribute. That makes the following ill-formed when using -fconcepts-ts: template requires foo [[nodiscard]] int f(T); This change moves all attributes that follow a requires-clause to the end of the function declarator. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: PR libstdc++/101782 * include/bits/ranges_base.h (ranges::begin, ranges::end) (ranges::rbegin, ranges::rend, ranges::size, ranges::ssize) (ranges::empty, ranges::data): Move attribute to the end of the declarator. * include/bits/stl_iterator.h (__gnu_cxx::__normal_iterator) (common_iterator): Likewise for non-member operator functions. * include/std/ranges (views::all, views::filter) (views::transform, views::take, views::take_while, views::drop) (views::drop_while, views::join, views::lazy_split) (views::split, views::counted, views::common, views::reverse) (views::elements): Likewise. * testsuite/std/ranges/access/101782.cc: New test. diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 614b6edf9df..1dac9680b4f 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -110,9 +110,9 @@ namespace ranges template<__maybe_borrowed_range _Tp> requires is_array_v> || __member_begin<_Tp> || __adl_begin<_Tp> - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) + [[nodiscard]] { if constexpr (is_array_v>) { @@ -162,9 +162,9 @@ namespace ranges template<__maybe_borrowed_range _Tp> requires is_bounded_array_v> || __member_end<_Tp> || __adl_end<_Tp> - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) + [[nodiscard]] { if constexpr (is_bounded_array_v>) { @@ -267,10 +267,10 @@ namespace ranges public: template<__maybe_borrowed_range _Tp> requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp> - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) + [[nodiscard]] { if constexpr (__member_rbegin<_Tp>) return __t.rbegin(); @@ -326,10 +326,10 @@ namespace ranges public: template<__maybe_borrowed_range _Tp> requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp> - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) + [[nodiscard]] { if constexpr (__member_rend<_Tp>) return __t.rend(); @@ -416,9 +416,9 @@ namespace ranges template requires is_bounded_array_v> || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp> - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) + [[nodiscard]] { if constexpr (is_bounded_array_v>) return extent_v>; @@ -437,9 +437,9 @@ namespace ranges // 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E) template requires requires (_Tp& __t) { _Size{}(__t); } - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(_Size{}(__t))) + [[nodiscard]] { auto __size = _Size{}(__t); using __size_type = decltype(__size); @@ -497,9 +497,9 @@ namespace ranges template requires __member_empty<_Tp> || __size0_empty<_Tp> || __eq_iter_empty<_Tp> - [[nodiscard]] constexpr bool operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) + [[nodiscard]] { if constexpr (__member_empty<_Tp>) return bool(__t.empty()); @@ -539,9 +539,9 @@ namespace ranges public: template<__maybe_borrowed_range _Tp> requires __member_data<_Tp> || __begin_data<_Tp> - [[nodiscard]] constexpr auto operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>()) + [[nodiscard]] { if constexpr (__member_data<_Tp>) return __t.data(); diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 3773d600b8f..053ae41e9c3 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1120,19 +1120,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template requires requires (_IteratorL __lhs, _IteratorR __rhs) { { __lhs == __rhs } -> std::convertible_to; } - [[nodiscard]] constexpr bool operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept(noexcept(__lhs.base() == __rhs.base())) + [[nodiscard]] { return __lhs.base() == __rhs.base(); } template - [[nodiscard]] constexpr std::__detail::__synth3way_t<_IteratorR, _IteratorL> operator<=>(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base()))) + [[nodiscard]] { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); } #else // Forward iterator requirements @@ -1984,10 +1984,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _Sent2> requires sentinel_for<_Sent, _It2> - [[nodiscard]] friend bool operator==(const common_iterator& __x, const common_iterator<_It2, _Sent2>& __y) + [[nodiscard]] { switch(__x._M_index << 2 | __y._M_index) { @@ -2007,10 +2007,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _Sent2> requires sentinel_for<_Sent, _It2> && equality_comparable_with<_It, _It2> - [[nodiscard]] friend bool operator==(const common_iterator& __x, const common_iterator<_It2, _Sent2>& __y) + [[nodiscard]] { switch(__x._M_index << 2 | __y._M_index) { @@ -2031,10 +2031,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _It2, sized_sentinel_for<_It> _Sent2> requires sized_sentinel_for<_Sent, _It2> - [[nodiscard]] friend iter_difference_t<_It2> operator-(const common_iterator& __x, const common_iterator<_It2, _Sent2>& __y) + [[nodiscard]] { switch(__x._M_index << 2 | __y._M_index) { diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 03a3778bb52..71b7dc7d295 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1126,10 +1126,10 @@ namespace views::__adaptor requires view> || __detail::__can_ref_view<_Range> || __detail::__can_subrange<_Range> - [[nodiscard]] constexpr auto operator()(_Range&& __r) const noexcept(_S_noexcept<_Range>()) + [[nodiscard]] { if constexpr (view>) return std::forward<_Range>(__r); @@ -1553,9 +1553,9 @@ namespace views::__adaptor { template requires __detail::__can_filter_view<_Range, _Pred> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Pred&& __p) const + [[nodiscard]] { return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p)); } @@ -1931,9 +1931,9 @@ namespace views::__adaptor { template requires __detail::__can_transform_view<_Range, _Fp> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Fp&& __f) const + [[nodiscard]] { return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f)); } @@ -2113,9 +2113,9 @@ namespace views::__adaptor { template requires __detail::__can_take_view<_Range, _Tp> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Tp&& __n) const + [[nodiscard]] { return take_view(std::forward<_Range>(__r), std::forward<_Tp>(__n)); } @@ -2241,9 +2241,9 @@ namespace views::__adaptor { template requires __detail::__can_take_while_view<_Range, _Pred> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Pred&& __p) const + [[nodiscard]] { return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p)); } @@ -2362,9 +2362,9 @@ namespace views::__adaptor { template requires __detail::__can_drop_view<_Range, _Tp> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Tp&& __n) const + [[nodiscard]] { return drop_view(std::forward<_Range>(__r), std::forward<_Tp>(__n)); } @@ -2451,9 +2451,9 @@ namespace views::__adaptor { template requires __detail::__can_drop_while_view<_Range, _Pred> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Pred&& __p) const + [[nodiscard]] { return drop_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p)); @@ -2814,9 +2814,9 @@ namespace views::__adaptor { template requires __detail::__can_join_view<_Range> - [[nodiscard]] constexpr auto operator()(_Range&& __r) const + [[nodiscard]] { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3474. Nesting join_views is broken because of CTAD @@ -3266,9 +3266,9 @@ namespace views::__adaptor { template requires __detail::__can_lazy_split_view<_Range, _Pattern> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Pattern&& __f) const + [[nodiscard]] { return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f)); } @@ -3475,9 +3475,9 @@ namespace views::__adaptor { template requires __detail::__can_split_view<_Range, _Pattern> - [[nodiscard]] constexpr auto operator()(_Range&& __r, _Pattern&& __f) const + [[nodiscard]] { return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f)); } @@ -3497,9 +3497,9 @@ namespace views::__adaptor struct _Counted { template - [[nodiscard]] constexpr auto operator()(_Iter __i, iter_difference_t<_Iter> __n) const + [[nodiscard]] { if constexpr (random_access_iterator<_Iter>) return subrange(__i, __i + __n); @@ -3619,9 +3619,9 @@ namespace views::__adaptor template requires __detail::__already_common<_Range> || __detail::__can_common_view<_Range> - [[nodiscard]] constexpr auto operator()(_Range&& __r) const + [[nodiscard]] { if constexpr (__detail::__already_common<_Range>) return views::all(std::forward<_Range>(__r)); @@ -3742,9 +3742,9 @@ namespace views::__adaptor requires __detail::__is_reverse_view> || __detail::__is_reversible_subrange> || __detail::__can_reverse_view<_Range> - [[nodiscard]] constexpr auto operator()(_Range&& __r) const + [[nodiscard]] { using _Tp = remove_cvref_t<_Range>; if constexpr (__detail::__is_reverse_view<_Tp>) @@ -4141,9 +4141,9 @@ namespace views::__adaptor { template requires __detail::__can_elements_view<_Nm, _Range> - [[nodiscard]] constexpr auto operator()(_Range&& __r) const + [[nodiscard]] { return elements_view, _Nm>{std::forward<_Range>(__r)}; } diff --git a/libstdc++-v3/testsuite/std/ranges/access/101782.cc b/libstdc++-v3/testsuite/std/ranges/access/101782.cc new file mode 100644 index 00000000000..abb0c8dab0f --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/access/101782.cc @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++20 -fconcepts-ts" } +// { dg-do compile { target c++20 } } + +// PR testsuite/101782 +// attribute-specifier-seq cannot follow requires-clause with -fconcepts-ts + +#include +#include +#include --9kPyG2yHaXB6Fy/O--