diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 762de9a763d6..8735cacf9410 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2018-05-31 Jonathan Wakely + + PR libstdc++/85951 + * include/std/type_traits [_GLIBCXX_USE_C99_STDINT_TR1]: Do not define + uint_least16_t and uint_least32_t. + (__make_unsigned): Define unconditionally. + (__make_unsigned_selector<_Tp, true, false>): Remove intermediate + typedefs. + (__make_unsigned_selector_base): New type to provide helper templates. + (__make_unsigned_selector<_Tp, false, true>): Reimplement using + __make_unsigned_selector_base helpers. + (__make_unsigned, __make_unsigned): Define. + (__make_signed_selector<_Tp, true, false>): Remove intermediate + typedefs. + (__make_signed, __make_signed) + (__make_signed)): Define unconditionally. + * testsuite/20_util/make_signed/requirements/typedefs-3.cc: Check + wchar_t, char16_t and char32_t are transformed correctly. + * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust + dg-error lineno. + * testsuite/20_util/make_unsigned/requirements/typedefs-3.cc: Check + wchar_t, char16_t and char32_t are transformed correctly. + * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Adjust + dg-error lineno. + 2018-05-29 Jonathan Wakely * include/std/variant (__erased_dtor): Qualify call to __get. diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 7c0ba7275110..4397c484f208 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -37,18 +37,6 @@ #include -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 -# if defined (__UINT_LEAST16_TYPE__) && defined(__UINT_LEAST32_TYPE__) -namespace std -{ - typedef __UINT_LEAST16_TYPE__ uint_least16_t; - typedef __UINT_LEAST32_TYPE__ uint_least32_t; -} -# else -# include -# endif -#endif - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -1576,12 +1564,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_unsigned { typedef unsigned long long __type; }; -#if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__) - template<> - struct __make_unsigned : __make_unsigned<__WCHAR_TYPE__> - { }; -#endif - #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> @@ -1612,36 +1594,77 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class __make_unsigned_selector<_Tp, true, false> { - typedef __make_unsigned::type> __unsignedt; - typedef typename __unsignedt::__type __unsigned_type; - typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; + using __unsigned_type + = typename __make_unsigned::type>::__type; public: - typedef typename __cv_unsigned::__type __type; + using __type + = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type; }; + class __make_unsigned_selector_base + { + protected: + template struct _List { }; + + template + struct _List<_Tp, _Up...> : _List<_Up...> + { static constexpr size_t __size = sizeof(_Tp); }; + + template + struct __select; + + template + struct __select<_Sz, _List<_Uint, _UInts...>, true> + { using __type = _Uint; }; + + template + struct __select<_Sz, _List<_Uint, _UInts...>, false> + : __select<_Sz, _List<_UInts...>> + { }; + }; + + // Choose unsigned integer type with the smallest rank and same size as _Tp template class __make_unsigned_selector<_Tp, false, true> + : __make_unsigned_selector_base { // With -fshort-enums, an enum may be as small as a char. - typedef unsigned char __smallest; - static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); - static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); - static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); - static const bool __b3 = sizeof(_Tp) <= sizeof(unsigned long); - typedef conditional<__b3, unsigned long, unsigned long long> __cond3; - typedef typename __cond3::type __cond3_type; - typedef conditional<__b2, unsigned int, __cond3_type> __cond2; - typedef typename __cond2::type __cond2_type; - typedef conditional<__b1, unsigned short, __cond2_type> __cond1; - typedef typename __cond1::type __cond1_type; + using _UInts = _List; - typedef typename conditional<__b0, __smallest, __cond1_type>::type - __unsigned_type; - typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; + using __unsigned_type = typename __select::__type; public: - typedef typename __cv_unsigned::__type __type; + using __type + = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type; + }; + + // wchar_t, char16_t and char32_t are integral types but are neither + // signed integer types not unsigned integer types, so must be + // transformed to the unsigned integer type with the smallest rank. + // Use the partial specialization for enumeration types to do that. +#if defined(_GLIBCXX_USE_WCHAR_T) + template<> + struct __make_unsigned + { + using __type + = typename __make_unsigned_selector::__type; + }; +#endif + + template<> + struct __make_unsigned + { + using __type + = typename __make_unsigned_selector::__type; + }; + + template<> + struct __make_unsigned + { + using __type + = typename __make_unsigned_selector::__type; }; // Given an integral/enum type, return the corresponding unsigned @@ -1686,21 +1709,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_signed { typedef signed long long __type; }; -#if defined(_GLIBCXX_USE_WCHAR_T) && defined(__WCHAR_UNSIGNED__) - template<> - struct __make_signed : __make_signed<__WCHAR_TYPE__> - { }; -#endif - -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - template<> - struct __make_signed : __make_signed - { }; - template<> - struct __make_signed : __make_signed - { }; -#endif - #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_signed @@ -1731,14 +1739,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class __make_signed_selector<_Tp, true, false> { - typedef __make_signed::type> __signedt; - typedef typename __signedt::__type __signed_type; - typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; + using __signed_type + = typename __make_signed::type>::__type; public: - typedef typename __cv_signed::__type __type; + using __type + = typename __match_cv_qualifiers<_Tp, __signed_type>::__type; }; + // Choose signed integer type with the smallest rank and same size as _Tp template class __make_signed_selector<_Tp, false, true> { @@ -1748,6 +1757,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __make_signed_selector<__unsigned_type>::__type __type; }; + // wchar_t, char16_t and char32_t are integral types but are neither + // signed integer types not unsigned integer types, so must be + // transformed to the signed integer type with the smallest rank. + // Use the partial specialization for enumeration types to do that. +#if defined(_GLIBCXX_USE_WCHAR_T) + template<> + struct __make_signed + { + using __type + = typename __make_signed_selector::__type; + }; +#endif + + template<> + struct __make_signed + { + using __type + = typename __make_signed_selector::__type; + }; + + template<> + struct __make_signed + { + using __type + = typename __make_signed_selector::__type; + }; + // Given an integral/enum type, return the corresponding signed // integer type. // Primary template. diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-3.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-3.cc index 3f50952fa3f3..79e0a700d097 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-3.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-3.cc @@ -59,8 +59,21 @@ using I4 = smallest_rank_t; static_assert(is_same::type, I4>::value, ""); static_assert(is_same::type, I4 const>::value, ""); -// PI libstdc++/60333 +// PR libstdc++/60333 enum E5 : long long { }; using I5 = smallest_rank_t; static_assert(is_same::type, I5>::value, ""); static_assert(is_same::type, I5 const>::value, ""); + +// PR libstdc++/85951 +using I6 = smallest_rank_t; +static_assert(is_same::type, I6>::value, ""); +static_assert(is_same::type, I6 const>::value, ""); +using I7 = smallest_rank_t; +static_assert(is_same::type, I7>::value, ""); +static_assert(is_same::type, I7 const>::value, ""); +#ifdef _GLIBCXX_USE_WCHAR_T +using I8 = smallest_rank_t; +static_assert(is_same::type, I8>::value, ""); +static_assert(is_same::type, I8 const>::value, ""); +#endif diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc index 8d46405165eb..13bca19c7e04 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc @@ -28,7 +28,7 @@ void test01() { using std::make_signed; - // Negative tests. + // Negative tests. typedef make_signed::type test1_type; typedef make_signed<__gnu_test::pod_uint>::type test2_type; @@ -47,4 +47,4 @@ void test01() // { dg-error "required from here" "" { target *-*-* } 39 } // { dg-error "required from here" "" { target *-*-* } 41 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1757 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1793 } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-3.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-3.cc index c901b0e08b12..895aa1c59b9d 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-3.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-3.cc @@ -59,8 +59,21 @@ using I4 = smallest_rank_t; static_assert(is_same::type, I4>::value, ""); static_assert(is_same::type, I4 const>::value, ""); -// PI libstdc++/60333 +// PR libstdc++/60333 enum E5 : long long { }; using I5 = smallest_rank_t; static_assert(is_same::type, I5>::value, ""); static_assert(is_same::type, I5 const>::value, ""); + +// PR libstdc++/85951 +using I6 = smallest_rank_t; +static_assert(is_same::type, I6>::value, ""); +static_assert(is_same::type, I6 const>::value, ""); +using I7 = smallest_rank_t; +static_assert(is_same::type, I7>::value, ""); +static_assert(is_same::type, I7 const>::value, ""); +#ifdef _GLIBCXX_USE_WCHAR_T +using I8 = smallest_rank_t; +static_assert(is_same::type, I8>::value, ""); +static_assert(is_same::type, I8 const>::value, ""); +#endif diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc index 93ae15723cf9..9df01550ea3d 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc @@ -28,7 +28,7 @@ void test01() { using std::make_unsigned; - // Negative tests. + // Negative tests. typedef make_unsigned::type test1_type; typedef make_unsigned<__gnu_test::pod_uint>::type test2_type; @@ -47,5 +47,5 @@ void test01() // { dg-error "required from here" "" { target *-*-* } 39 } // { dg-error "required from here" "" { target *-*-* } 41 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1653 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1676 }