From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by sourceware.org (Postfix) with ESMTP id 39524386F832 for ; Wed, 19 Aug 2020 16:00:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 39524386F832 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-491-UpHIFP3RMbGMg7VIFayBqw-1; Wed, 19 Aug 2020 12:00:06 -0400 X-MC-Unique: UpHIFP3RMbGMg7VIFayBqw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 973F310054FF; Wed, 19 Aug 2020 16:00:05 +0000 (UTC) Received: from localhost (unknown [10.33.36.183]) by smtp.corp.redhat.com (Postfix) with ESMTP id 30DC6600E4; Wed, 19 Aug 2020 16:00:04 +0000 (UTC) Date: Wed, 19 Aug 2020 17:00:04 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Make __int128 meet integer-class requirements [PR 96042] Message-ID: <20200819160004.GA11512@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="G4iJoqBmSsgzjUCe" Content-Disposition: inline X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, 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-List-Received-Date: Wed, 19 Aug 2020 16:00:12 -0000 --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Because __int128 can be used as the difference type for iota_view, we need to ensure that it meets the requirements of an integer-class type. The requirements in [iterator.concept.winc] p10 include numeric_limits being specialized and giving meaningful answers. Currently we only specialize numeric_limits for non-standard integer types in non-strict modes. However, nothing prevents us from defining an explicit specialization for any implementation-defined type, so it doesn't matter whether std::is_integral<__int128> is true or not. This patch ensures that the numeric_limits specializations for signed and unsigned __int128 are defined whenever __int128 is available. It also makes the __numeric_traits and __int_limits helpers work for __int128, via a new __gnu_cxx::__is_integer_nonstrict trait. libstdc++-v3/ChangeLog: PR libstdc++/96042 * include/ext/numeric_traits.h (__is_integer_nonstrict): New trait which is true for 128-bit integers even in strict modes. (__numeric_traits_integer, __numeric_traits): Use __is_integer_nonstrict instead of __is_integer. * include/std/limits [__STRICT_ANSI__ && __SIZEOF_INT128__] (numeric_limits<__int128>, (numeric_limits): Define. * testsuite/std/ranges/iota/96042.cc: New test. Tested powerpc64le-linux. Committed to trunk. I'll backport this to gcc-10 too. --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 386fd16c551188e20d5b1684b7139e4269f9a739 Author: Jonathan Wakely Date: Wed Aug 19 16:27:25 2020 libstdc++: Make __int128 meet integer-class requirements [PR 96042] Because __int128 can be used as the difference type for iota_view, we need to ensure that it meets the requirements of an integer-class type. The requirements in [iterator.concept.winc] p10 include numeric_limits being specialized and giving meaningful answers. Currently we only specialize numeric_limits for non-standard integer types in non-strict modes. However, nothing prevents us from defining an explicit specialization for any implementation-defined type, so it doesn't matter whether std::is_integral<__int128> is true or not. This patch ensures that the numeric_limits specializations for signed and unsigned __int128 are defined whenever __int128 is available. It also makes the __numeric_traits and __int_limits helpers work for __int128, via a new __gnu_cxx::__is_integer_nonstrict trait. libstdc++-v3/ChangeLog: PR libstdc++/96042 * include/ext/numeric_traits.h (__is_integer_nonstrict): New trait which is true for 128-bit integers even in strict modes. (__numeric_traits_integer, __numeric_traits): Use __is_integer_nonstrict instead of __is_integer. * include/std/limits [__STRICT_ANSI__ && __SIZEOF_INT128__] (numeric_limits<__int128>, (numeric_limits): Define. * testsuite/std/ranges/iota/96042.cc: New test. diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h index 69f286d7be7..585ecc0ba9f 100644 --- a/libstdc++-v3/include/ext/numeric_traits.h +++ b/libstdc++-v3/include/ext/numeric_traits.h @@ -51,11 +51,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION (__glibcxx_signed(_Tp) ? \ (((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0) + template + struct __is_integer_nonstrict + : public std::__is_integer<_Tp> + { }; + +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ + // __is_integer<__int128> is false, but we still want to allow it here. + template<> struct __is_integer_nonstrict<__int128> + { enum { __value = 1 }; typedef std::__true_type __type; }; + + template<> struct __is_integer_nonstrict + { enum { __value = 1 }; typedef std::__true_type __type; }; +#endif + template struct __numeric_traits_integer { #if __cplusplus >= 201103L - static_assert(std::__is_integer<_Value>::__value, + static_assert(__is_integer_nonstrict<_Value>::__value, "invalid specialization"); #endif @@ -132,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __numeric_traits - : public __conditional_type::__value, + : public __conditional_type<__is_integer_nonstrict<_Value>::__value, __numeric_traits_integer<_Value>, __numeric_traits_floating<_Value> >::__type { }; diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits index f5e403be727..20883ba6403 100644 --- a/libstdc++-v3/include/std/limits +++ b/libstdc++-v3/include/std/limits @@ -1477,8 +1477,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = round_toward_zero; }; -#if !defined(__STRICT_ANSI__) - #define __INT_N(TYPE, BITSIZE, EXT, UEXT) \ template<> \ struct numeric_limits \ @@ -1632,6 +1630,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __INT_N_U201103(TYPE) #endif +#if !defined(__STRICT_ANSI__) #ifdef __GLIBCXX_TYPE_INT_N_0 __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0, __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), @@ -1653,11 +1652,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3)) #endif +#elif defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ + __INT_N(__int128, 128, + __INT_N_201103 (__int128), + __INT_N_U201103 (__int128)) +#endif + #undef __INT_N #undef __INT_N_201103 #undef __INT_N_U201103 -#endif /// numeric_limits specialization. template<> diff --git a/libstdc++-v3/testsuite/std/ranges/iota/96042.cc b/libstdc++-v3/testsuite/std/ranges/iota/96042.cc new file mode 100644 index 00000000000..6f5c8f61fd2 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/iota/96042.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 +// . + +// { dg-options "-std=c++2a" } +// { dg-do compile { target c++2a } } + +#include + +void +test01() +{ + // PR libstdc++/96042 + using V = std::ranges::iota_view; + using D = std::ranges::range_difference_t; + using L = std::numeric_limits; + static_assert( L::is_specialized ); + static_assert( L::is_signed ); + static_assert( L::is_integer ); + static_assert( L::is_exact ); + static_assert( L::digits > std::numeric_limits::digits ); + static_assert( L::digits10 == static_cast(L::digits * 0.30103) ); + static_assert( L::min() == (D(1) << L::digits) ); + static_assert( L::max() == ~L::min() ); + static_assert( L::lowest() == L::min() ); +} --G4iJoqBmSsgzjUCe--