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 [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 4B6783858034 for ; Mon, 13 Dec 2021 11:16:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4B6783858034 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-22-1qyLXOmYMS6VKo57dn9aOw-1; Mon, 13 Dec 2021 06:16:39 -0500 X-MC-Unique: 1qyLXOmYMS6VKo57dn9aOw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D03EF64083; Mon, 13 Dec 2021 11:16:38 +0000 (UTC) Received: from localhost (unknown [10.33.36.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 821F0709AA; Mon, 13 Dec 2021 11:16:38 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Make ranges::size and ranges::empty check for unbounded arrays Date: Mon, 13 Dec 2021 11:16:37 +0000 Message-Id: <20211213111637.1941138-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" 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, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, URIBL_SBL_A 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: Mon, 13 Dec 2021 11:16:43 -0000 Tested powerpc64le-linux, pushed to trunk. Passing IncompleteType(&)[] to ranges::begin produces an error outside the immediate context, which is fine for ranges::begin, but it means that we fail to enforce the SFINAE-able constraints for ranges::size and ranges::size. They should not be callable for any array of unknown bound, whether the type is complete or not. Because we don't enforce that in their constraints, we get a hard error when they try to use ranges::begin. This simply adds explicit checks for arrays of unknown bound to the constraints for ranges::size and ranges::empty. We only need to check it for the __sentinel_size and __eq_iter_empty concepts, because those are the ones that are relevant to arrays, and which try to use ranges::begin. libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (ranges::size, ranges::empty): Add explicit check for unbounded arrays before using ranges::begin. * testsuite/std/ranges/access/empty.cc: Check handling of unbounded arrays. * testsuite/std/ranges/access/size.cc: Likewise. --- libstdc++-v3/include/bits/ranges_base.h | 4 ++++ libstdc++-v3/testsuite/std/ranges/access/empty.cc | 10 ++++++++++ libstdc++-v3/testsuite/std/ranges/access/size.cc | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 43b0b9f7bf3..bf95823668b 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -383,6 +383,8 @@ namespace ranges template concept __sentinel_size = requires(_Tp& __t) { + requires (!is_unbounded_array_v>); + { _Begin{}(__t) } -> forward_iterator; { _End{}(__t) } -> sized_sentinel_for; @@ -466,6 +468,8 @@ namespace ranges template concept __eq_iter_empty = requires(_Tp& __t) { + requires (!is_unbounded_array_v>); + { _Begin{}(__t) } -> forward_iterator; bool(_Begin{}(__t) == _End{}(__t)); diff --git a/libstdc++-v3/testsuite/std/ranges/access/empty.cc b/libstdc++-v3/testsuite/std/ranges/access/empty.cc index 3cad4740124..83b40872bd4 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/empty.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/empty.cc @@ -121,6 +121,16 @@ test04() static_assert( ! noexcept(std::ranges::empty(E3{})) ); } +template + concept has_empty = requires (T& t) { std::ranges::empty(t); }; + +// If T is an array of unknown bound, ranges::empty(E) is ill-formed. +static_assert( ! has_empty ); +static_assert( ! has_empty ); +static_assert( ! has_empty ); +struct Incomplete; +static_assert( ! has_empty ); + int main() { diff --git a/libstdc++-v3/testsuite/std/ranges/access/size.cc b/libstdc++-v3/testsuite/std/ranges/access/size.cc index c7e4f78f96a..24857975f7b 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/size.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/size.cc @@ -122,6 +122,16 @@ test06() static_assert( std::ranges::size(R{}) == 42 ); } +template + concept has_size = requires (T& t) { std::ranges::size(t); }; + +// If T is an array of unknown bound, ranges::size(E) is ill-formed. +static_assert( ! has_size ); +static_assert( ! has_size ); +static_assert( ! has_size ); +struct Incomplete; +static_assert( ! has_size ); + int main() { -- 2.31.1