From patchwork Wed Jan 15 17:02:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1223724 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=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-517457-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=lZ8J7wLO; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=UWm7sKSC; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47yYXs578lz9sP3 for ; Thu, 16 Jan 2020 04:02:37 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=MVPTerXUBuDb2f+c6E40enfMdGpexA63N2rDC1TUg6HHT+1MYDh61 uLVgs1dj9qXZPIn/OBpep6ni+MaxtHhGzieuoV5t5sapbCB45BudSerrdRMvY5Yx wDdFJ4Aqe2n3a3E0heR2lJ+Ut8OlvRQhxjjT+aovh/t4JoUJzShwmo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=qifZStoOHSg1xds+ennlys68//0=; b=lZ8J7wLOemK4D04Qhce/ hdsAkjnB9rEijbINjgDhq/RwHNUyHGNK4lPnvtJJOBxnqriw16ML2+GxtIV7xSlx qhoBiNMOamOmA7HnN8AZO1yti5v18GeBiK0Bt+i8hd3lW7lTpyQGfh0m+IdDs7OH qD2VDGcIp42+BdxGSZgfjx0= Received: (qmail 26467 invoked by alias); 15 Jan 2020 17:02:22 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 26434 invoked by uid 89); 15 Jan 2020 17:02:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=_Iterator, 34722, _iterator X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (207.211.31.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 15 Jan 2020 17:02:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579107729; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=CyzKldE/6Cgen2AgCmOMvphkJtHVLcVX5ZnXvfwctTg=; b=UWm7sKSCA0yffrN+L2wQabo/YDF150ut0dOn3gsl+60IMeDxZDgP26PScU6uzLBR4r1PHU 0pmj5t1e81c6gUW9q09SEHJJXZxLvQQQXkD5CPwhg5OQRMy+wVevDmb0RCL1yOm0KWF5xI 67p5ncLaXQh/3OG5b9tG0RjjWs/qYVc= 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-377-6RRn8rlpOkmyZ9hKt9JeGQ-1; Wed, 15 Jan 2020 12:02:07 -0500 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 A61531005510; Wed, 15 Jan 2020 17:02:06 +0000 (UTC) Received: from localhost (unknown [10.33.36.10]) by smtp.corp.redhat.com (Postfix) with ESMTP id 332AC19756; Wed, 15 Jan 2020 17:02:06 +0000 (UTC) Date: Wed, 15 Jan 2020 17:02:05 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] libstdc++: Fix weakly_incrementable to allow __int128 (PR 93267) Message-ID: <20200115170205.GA548679@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Mimecast-Spam-Score: 0 Content-Disposition: inline The __iota_diff_t alias can be the type __int128, but that does not satisfy the signed_integral and __is_signed_integer_like concepts when __STRICT_ANSI__ is defined (which is true for -std=c++2a). Because weakly_incrementable is defined in terms of signed_integral, it is not satisfied by __int128, which means iota_view's iterator doesn't always satisfy input_or_output_iterator and so iota_view is not always a range. The solution is to define __max_size_type and __max_diff_type using __int128, so that __is_signed_integer_like allows __int128, and then make weakly_incrementable use __is_signed_integer_like instead of signed_integral. PR libstdc++/93267 * include/bits/iterator_concepts.h (__max_diff_type, __max_size_type): Move here from and define using __int128 when available. (__is_integer_like, __is_signed_integer_like): Move here from . (weakly_incrementable): Use __is_signed_integer_like. * include/bits/range_access.h (__max_diff_type, __max_size_type) (__is_integer_like, __is_signed_integer_like): Move to . (__make_unsigned_like_t): Move here from . * include/std/ranges (__make_unsigned_like_t): Move to . (iota_view): Replace using-directive with using-declarations. * testsuite/std/ranges/iota/93267.cc: New test. * testsuite/std/ranges/iota_view.cc: Move to new 'iota' sub-directory. Tested powerpc64le-linux, committed to trunk. commit 2a0f6c61b4db19535c632be68bddad74b6adb6cf Author: Jonathan Wakely Date: Wed Jan 15 14:09:35 2020 +0000 libstdc++: Fix weakly_incrementable to allow __int128 (PR 93267) The __iota_diff_t alias can be the type __int128, but that does not satisfy the signed_integral and __is_signed_integer_like concepts when __STRICT_ANSI__ is defined (which is true for -std=c++2a). Because weakly_incrementable is defined in terms of signed_integral, it is not satisfied by __int128, which means iota_view's iterator doesn't always satisfy input_or_output_iterator and so iota_view is not always a range. The solution is to define __max_size_type and __max_diff_type using __int128, so that __is_signed_integer_like allows __int128, and then make weakly_incrementable use __is_signed_integer_like instead of signed_integral. PR libstdc++/93267 * include/bits/iterator_concepts.h (__max_diff_type, __max_size_type): Move here from and define using __int128 when available. (__is_integer_like, __is_signed_integer_like): Move here from . (weakly_incrementable): Use __is_signed_integer_like. * include/bits/range_access.h (__max_diff_type, __max_size_type) (__is_integer_like, __is_signed_integer_like): Move to . (__make_unsigned_like_t): Move here from . * include/std/ranges (__make_unsigned_like_t): Move to . (iota_view): Replace using-directive with using-declarations. * testsuite/std/ranges/iota/93267.cc: New test. * testsuite/std/ranges/iota_view.cc: Move to new 'iota' sub-directory. diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index 4ba32a0859e..bf581597229 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -492,6 +492,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = std::forward<_Tp>(__t); }; + namespace ranges::__detail + { +#if __SIZEOF_INT128__ + using __max_diff_type = __int128; + using __max_size_type = unsigned __int128; +#else + using __max_diff_type = long long; + using __max_size_type = unsigned long long; +#endif + + template + concept __is_integer_like = integral<_Tp> + || same_as<_Tp, __max_diff_type> || same_as<_Tp, __max_size_type>; + + template + concept __is_signed_integer_like = signed_integral<_Tp> + || same_as<_Tp, __max_diff_type>; + + } // namespace ranges::__detail + + namespace __detail { using ranges::__detail::__is_signed_integer_like; } + /// Requirements on types that can be incremented with ++. template concept weakly_incrementable = default_initializable<_Iter> @@ -499,7 +521,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && requires(_Iter __i) { typename iter_difference_t<_Iter>; - requires signed_integral>; + requires __detail::__is_signed_integer_like>; { ++__i } -> same_as<_Iter&>; __i++; }; diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h index 721c755f48c..8b546a58840 100644 --- a/libstdc++-v3/include/bits/range_access.h +++ b/libstdc++-v3/include/bits/range_access.h @@ -347,22 +347,15 @@ namespace ranges namespace __detail { - using __max_diff_type = long long; - using __max_size_type = unsigned long long; - - template - concept __is_integer_like = integral<_Tp> - || same_as<_Tp, __max_diff_type> || same_as<_Tp, __max_size_type>; - - template - concept __is_signed_integer_like = signed_integral<_Tp> - || same_as<_Tp, __max_diff_type>; - template constexpr make_unsigned_t<_Tp> __to_unsigned_like(_Tp __t) noexcept { return __t; } + template> + using __make_unsigned_like_t + = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>; + // Part of the constraints of ranges::safe_range template concept __maybe_safe_range diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 888414a8fd6..ea558c76c9d 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -244,10 +244,6 @@ namespace ranges = !range<_Tp> && __pair_like<_Tp> && sentinel_for, tuple_element_t<0, _Tp>>; - template> - using __make_unsigned_like_t - = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>; - } // namespace __detail enum class subrange_kind : bool { unsized, sized }; @@ -717,7 +713,8 @@ namespace ranges constexpr _Iterator& operator+=(difference_type __n) requires __detail::__advanceable<_Winc> { - using namespace __detail; + using __detail::__is_integer_like; + using __detail::__is_signed_integer_like; if constexpr (__is_integer_like<_Winc> && !__is_signed_integer_like<_Winc>) { @@ -734,7 +731,8 @@ namespace ranges constexpr _Iterator& operator-=(difference_type __n) requires __detail::__advanceable<_Winc> { - using namespace __detail; + using __detail::__is_integer_like; + using __detail::__is_signed_integer_like; if constexpr (__is_integer_like<_Winc> && !__is_signed_integer_like<_Winc>) { @@ -804,7 +802,8 @@ namespace ranges operator-(const _Iterator& __x, const _Iterator& __y) requires __detail::__advanceable<_Winc> { - using namespace __detail; + using __detail::__is_integer_like; + using __detail::__is_signed_integer_like; using _Dt = difference_type; if constexpr (__is_integer_like<_Winc>) { @@ -892,7 +891,8 @@ namespace ranges || (integral<_Winc> && integral<_Bound>) || sized_sentinel_for<_Bound, _Winc> { - using namespace __detail; + using __detail::__is_integer_like; + using __detail::__to_unsigned_like; if constexpr (__is_integer_like<_Winc> && __is_integer_like<_Bound>) return (_M_value < 0) ? ((_M_bound < 0) diff --git a/libstdc++-v3/testsuite/std/ranges/iota/93267.cc b/libstdc++-v3/testsuite/std/ranges/iota/93267.cc new file mode 100644 index 00000000000..39b3c771b54 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/iota/93267.cc @@ -0,0 +1,30 @@ +// 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=c++2a" } +// { dg-do compile { target c++2a } } + +#include + +void +test01() +{ + // PR libstdc++/93267 + std::ranges::iota_view i(0, 3); + static_assert( std::weakly_incrementable ); + (void) std::ranges::begin(i); +}