From patchwork Tue Jun 15 18:28:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1492412 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=eTUYPys9; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G4H592YGyz9sWD for ; Wed, 16 Jun 2021 04:33:33 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C49F73838034 for ; Tue, 15 Jun 2021 18:33:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C49F73838034 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1623782010; bh=aiu9EHXgQd2rXGC5a7Am6V2YYLQ2+OkLTtZrCWmin+c=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=eTUYPys96bEYPP8Q8slUJA5HIv59y6V7xSXLb13HQsGQJuyJKc/3n96YR2evFM7t1 08+XOLy8eQ8q/0lsURo1gV9on8wZu557x/oTatH5fij3TXFJcHcZ34g/5kk3AzXk+w GTlI4Ri4ZcIZyxZf1Fka+9HVd4z726tiHUV8GdBM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 DA9593838008 for ; Tue, 15 Jun 2021 18:28:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DA9593838008 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-233-X7y4rc7uOWSS8nHCmTeBkg-1; Tue, 15 Jun 2021 14:28:17 -0400 X-MC-Unique: X7y4rc7uOWSS8nHCmTeBkg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9480B91274; Tue, 15 Jun 2021 18:28:16 +0000 (UTC) Received: from localhost (unknown [10.33.36.175]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3B30060C0F; Tue, 15 Jun 2021 18:28:16 +0000 (UTC) Date: Tue, 15 Jun 2021 19:28:15 +0100 To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Make ranges CPOs final and not addressable Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FILL_THIS_FORM, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This restricts the API of the CPOs and other function objects so they cannot be misused by deriving from them or taking their addresses. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (ranges::begin, ranges::end) (ranges::cbegin, ranges::cend, ranges::rbeing, ranges::rend) (ranges::crbegin, ranges::crend, ranges::size, ranges::ssize) (ranges::empty, ranges::data, ranges::cdata): Make types final. Add deleted operator& overloads. (ranges::advance, ranges::distance, ranges::next, ranges::prev): Likewise. * testsuite/std/ranges/headers/ranges/synopsis.cc: Replace ill-formed & expressions with using-declarations. Add checks for other function objects. Tested powerpc64le-linux. Committed to trunk. commit 8b93548778a487f31f21e0c6afe7e0bde9711fc4 Author: Jonathan Wakely Date: Tue Jun 15 17:54:53 2021 libstdc++: Make ranges CPOs final and not addressable This restricts the API of the CPOs and other function objects so they cannot be misused by deriving from them or taking their addresses. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (ranges::begin, ranges::end) (ranges::cbegin, ranges::cend, ranges::rbeing, ranges::rend) (ranges::crbegin, ranges::crend, ranges::size, ranges::ssize) (ranges::empty, ranges::data, ranges::cdata): Make types final. Add deleted operator& overloads. (ranges::advance, ranges::distance, ranges::next, ranges::prev): Likewise. * testsuite/std/ranges/headers/ranges/synopsis.cc: Replace ill-formed & expressions with using-declarations. Add checks for other function objects. diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index a63ef8eb7f4..e392c370fcd 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -91,7 +91,7 @@ namespace ranges using std::ranges::__detail::__maybe_borrowed_range; using std::__detail::__range_iter_t; - struct _Begin + struct _Begin final { private: template @@ -106,6 +106,8 @@ namespace ranges return noexcept(__decay_copy(begin(std::declval<_Tp&>()))); } + void operator&() const = delete; + public: template<__maybe_borrowed_range _Tp> requires is_array_v> || __member_begin<_Tp> @@ -142,7 +144,7 @@ namespace ranges { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>; }; - struct _End + struct _End final { private: template @@ -157,6 +159,8 @@ namespace ranges return noexcept(__decay_copy(end(std::declval<_Tp&>()))); } + void operator&() const = delete; + public: template<__maybe_borrowed_range _Tp> requires is_bounded_array_v> @@ -189,7 +193,7 @@ namespace ranges return static_cast(__t); } - struct _CBegin + struct _CBegin final { template constexpr auto @@ -199,9 +203,11 @@ namespace ranges { return _Begin{}(__cust_access::__as_const<_Tp>(__e)); } + + void operator&() const = delete; }; - struct _CEnd + struct _CEnd final { template constexpr auto @@ -211,6 +217,8 @@ namespace ranges { return _End{}(__cust_access::__as_const<_Tp>(__e)); } + + void operator&() const = delete; }; template @@ -236,7 +244,7 @@ namespace ranges { _End{}(__t) } -> same_as; }; - struct _RBegin + struct _RBegin final { private: template @@ -260,6 +268,8 @@ namespace ranges } } + void operator&() const = delete; + public: template<__maybe_borrowed_range _Tp> requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp> @@ -294,7 +304,7 @@ namespace ranges -> sentinel_for(__t)))>; }; - struct _REnd + struct _REnd final { private: template @@ -318,6 +328,8 @@ namespace ranges } } + void operator&() const = delete; + public: template<__maybe_borrowed_range _Tp> requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp> @@ -334,7 +346,7 @@ namespace ranges } }; - struct _CRBegin + struct _CRBegin final { template constexpr auto @@ -344,9 +356,11 @@ namespace ranges { return _RBegin{}(__cust_access::__as_const<_Tp>(__e)); } + + void operator&() const = delete; }; - struct _CREnd + struct _CREnd final { template constexpr auto @@ -356,6 +370,8 @@ namespace ranges { return _REnd{}(__cust_access::__as_const<_Tp>(__e)); } + + void operator&() const = delete; }; template @@ -386,7 +402,7 @@ namespace ranges __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t)); }; - struct _Size + struct _Size final { private: template @@ -404,6 +420,8 @@ namespace ranges - _Begin{}(std::declval<_Tp&>())); } + void operator&() const = delete; + public: template requires is_bounded_array_v> @@ -422,7 +440,7 @@ namespace ranges } }; - struct _SSize + struct _SSize final { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E) @@ -451,6 +469,8 @@ namespace ranges else // Must be one of __max_diff_type or __max_size_type. return __detail::__max_diff_type(__size); } + + void operator&() const = delete; }; template @@ -467,7 +487,7 @@ namespace ranges bool(_Begin{}(__t) == _End{}(__t)); }; - struct _Empty + struct _Empty final { private: template @@ -483,6 +503,8 @@ namespace ranges == _End{}(std::declval<_Tp&>()))); } + void operator&() const = delete; + public: template requires __member_empty<_Tp> || __size0_empty<_Tp> @@ -512,7 +534,7 @@ namespace ranges template concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>; - struct _Data + struct _Data final { private: template @@ -525,6 +547,8 @@ namespace ranges return noexcept(_Begin{}(std::declval<_Tp&>())); } + void operator&() const = delete; + public: template<__maybe_borrowed_range _Tp> requires __member_data<_Tp> || __begin_data<_Tp> @@ -538,7 +562,7 @@ namespace ranges } }; - struct _CData + struct _CData final { template constexpr auto @@ -548,6 +572,8 @@ namespace ranges { return _Data{}(__cust_access::__as_const<_Tp>(__e)); } + + void operator&() const = delete; }; } // namespace __cust_access @@ -669,7 +695,7 @@ namespace ranges // [range.iter.ops] range iterator operations - struct __advance_fn + struct __advance_fn final { template constexpr void @@ -774,11 +800,13 @@ namespace ranges return __n; } } + + void operator&() const = delete; }; inline constexpr __advance_fn advance{}; - struct __distance_fn + struct __distance_fn final { template _Sent> constexpr iter_difference_t<_It> @@ -807,11 +835,13 @@ namespace ranges else return (*this)(ranges::begin(__r), ranges::end(__r)); } + + void operator&() const = delete; }; inline constexpr __distance_fn distance{}; - struct __next_fn + struct __next_fn final { template constexpr _It @@ -844,11 +874,13 @@ namespace ranges ranges::advance(__x, __n, __bound); return __x; } + + void operator&() const = delete; }; inline constexpr __next_fn next{}; - struct __prev_fn + struct __prev_fn final { template constexpr _It @@ -873,6 +905,8 @@ namespace ranges ranges::advance(__x, -__n, __bound); return __x; } + + void operator&() const = delete; }; inline constexpr __prev_fn prev{}; diff --git a/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc b/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc index 115b157fd6c..ea26b505678 100644 --- a/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc +++ b/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc @@ -33,12 +33,22 @@ namespace __gnu_test { constexpr const bool* disable_sized_range = &std::ranges::disable_sized_range; - constexpr auto* begin = &std::ranges::begin; - constexpr auto* end = &std::ranges::end; - constexpr auto* cbegin = &std::ranges::cbegin; - constexpr auto* cend = &std::ranges::cend; - constexpr auto* rbegin = &std::ranges::rbegin; - constexpr auto* rend = &std::ranges::rend; - constexpr auto* crbegin = &std::ranges::crbegin; - constexpr auto* crend = &std::ranges::crend; + using std::ranges::begin; + using std::ranges::end; + using std::ranges::cbegin; + using std::ranges::cend; + using std::ranges::rbegin; + using std::ranges::rend; + using std::ranges::crbegin; + using std::ranges::crend; + using std::ranges::size; + using std::ranges::ssize; + using std::ranges::empty; + using std::ranges::data; + using std::ranges::cdata; + + using std::ranges::advance; + using std::ranges::distance; + using std::ranges::next; + using std::ranges::prev; }