mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			re PR libstdc++/60333 (type_traits make_signed, make_unsigned missing support for long long enumerations)
PR libstdc++/60333 * include/std/type_traits (__make_unsigned_selector<_Tp, false, true>): Handle enumeration types larger than sizeof(long). (__make_signed_selector<_Tp, false, true>): Find unsigned type then make it signed. * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/make_signed/requirements/typedefs-3.cc: New. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Adjust dg-error. * testsuite/20_util/make_unsigned/requirements/typedefs-3.cc: New. From-SVN: r222526
This commit is contained in:
		
							parent
							
								
									956d18149e
								
							
						
					
					
						commit
						73d81d3a6b
					
				|  | @ -1,5 +1,18 @@ | |||
| 2015-04-28  Jonathan Wakely  <jwakely@redhat.com> | ||||
| 
 | ||||
| 	PR libstdc++/60333 | ||||
| 	* include/std/type_traits (__make_unsigned_selector<_Tp, false, true>): | ||||
| 	Handle enumeration types larger than sizeof(long). | ||||
| 	(__make_signed_selector<_Tp, false, true>): Find unsigned type then | ||||
| 	make it signed. | ||||
| 	* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error. | ||||
| 	* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: | ||||
| 	Likewise. | ||||
| 	* testsuite/20_util/make_signed/requirements/typedefs-3.cc: New. | ||||
| 	* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Adjust | ||||
| 	dg-error. | ||||
| 	* testsuite/20_util/make_unsigned/requirements/typedefs-3.cc: New. | ||||
| 
 | ||||
| 	PR libstdc++/61645 | ||||
| 	* include/bits/forward_list.h (forward_list::splice_after): Add | ||||
| 	noexcept. | ||||
|  |  | |||
|  | @ -1739,13 +1739,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION | |||
|       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); | ||||
|       typedef conditional<__b2, unsigned int, unsigned long> __cond2; | ||||
|       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; | ||||
| 
 | ||||
|       typedef typename conditional<__b0, __smallest, __cond1_type>::type | ||||
| 	__unsigned_type; | ||||
|       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; | ||||
| 
 | ||||
|     public: | ||||
|       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; | ||||
|       typedef typename __cv_unsigned::__type __type; | ||||
|     }; | ||||
| 
 | ||||
|   // Given an integral/enum type, return the corresponding unsigned | ||||
|  | @ -1846,18 +1853,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION | |||
|   template<typename _Tp> | ||||
|     class __make_signed_selector<_Tp, false, true> | ||||
|     { | ||||
|       // With -fshort-enums, an enum may be as small as a char. | ||||
|       typedef signed char __smallest; | ||||
|       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); | ||||
|       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); | ||||
|       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); | ||||
|       typedef conditional<__b2, signed int, signed long> __cond2; | ||||
|       typedef typename __cond2::type __cond2_type; | ||||
|       typedef conditional<__b1, signed short, __cond2_type> __cond1; | ||||
|       typedef typename __cond1::type __cond1_type; | ||||
|       typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; | ||||
| 
 | ||||
|     public: | ||||
|       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; | ||||
|       typedef typename __make_signed_selector<__unsigned_type>::__type __type; | ||||
|     }; | ||||
| 
 | ||||
|   // Given an integral/enum type, return the corresponding signed | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ | |||
| // with this library; see the file COPYING3.  If not see
 | ||||
| // <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| // { dg-error "static assertion failed" "" { target *-*-* } 2204 }
 | ||||
| // { dg-error "static assertion failed" "" { target *-*-* } 2203 }
 | ||||
| 
 | ||||
| #include <utility> | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,67 @@ | |||
| // { dg-options "-std=gnu++11" }
 | ||||
| // { dg-do compile }
 | ||||
| 
 | ||||
| // Copyright (C) 2015 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
 | ||||
| // <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| #include <type_traits> | ||||
| 
 | ||||
| template<typename T, typename I0, typename... I> | ||||
| struct smallest_rank | ||||
| : std::conditional< sizeof(T) == sizeof(I0), | ||||
|                     I0, | ||||
|                     typename smallest_rank<T, I...>::type > | ||||
| { }; | ||||
| 
 | ||||
| template<typename T, typename I0> | ||||
| struct smallest_rank<T, I0> | ||||
| { using type = I0; }; | ||||
| 
 | ||||
| template<typename T> | ||||
| using smallest_rank_t | ||||
|   = typename smallest_rank<typename std::remove_cv<T>::type, | ||||
|                            signed char, signed short, signed int, | ||||
|                            signed long, signed long long>::type; | ||||
| 
 | ||||
| using std::make_signed; | ||||
| using std::is_same; | ||||
| 
 | ||||
| enum E1 : char { }; | ||||
| using I1 = smallest_rank_t<E1>; | ||||
| static_assert(is_same<make_signed<E1>::type,       I1>::value, ""); | ||||
| static_assert(is_same<make_signed<E1 const>::type, I1 const>::value, ""); | ||||
| 
 | ||||
| enum E2 : short { }; | ||||
| using I2 = smallest_rank_t<E2>; | ||||
| static_assert(is_same<make_signed<E2>::type,       I2>::value, ""); | ||||
| static_assert(is_same<make_signed<E2 const>::type, I2 const>::value, ""); | ||||
| 
 | ||||
| enum E3 : int { }; | ||||
| using I3 = smallest_rank_t<E3>; | ||||
| static_assert(is_same<make_signed<E3>::type,       I3>::value, ""); | ||||
| static_assert(is_same<make_signed<E3 const>::type, I3 const>::value, ""); | ||||
| 
 | ||||
| enum E4 : long { }; | ||||
| using I4 = smallest_rank_t<E4>; | ||||
| static_assert(is_same<make_signed<E4>::type,       I4>::value, ""); | ||||
| static_assert(is_same<make_signed<E4 const>::type, I4 const>::value, ""); | ||||
| 
 | ||||
| // PI libstdc++/60333
 | ||||
| enum E5 : long long { }; | ||||
| using I5 = smallest_rank_t<E5>; | ||||
| static_assert(is_same<make_signed<E5>::type, I5>::value, ""); | ||||
| static_assert(is_same<make_signed<E5 const>::type, I5 const>::value, ""); | ||||
|  | @ -48,5 +48,4 @@ void test01() | |||
| // { dg-error "required from here" "" { target *-*-* } 40 }
 | ||||
| // { dg-error "required from here" "" { target *-*-* } 42 }
 | ||||
| 
 | ||||
| // { dg-error "invalid use of incomplete type" "" { target *-*-* } 1869 }
 | ||||
| // { dg-error "declaration of" "" { target *-*-* } 1833 }
 | ||||
| // { dg-error "invalid use of incomplete type" "" { target *-*-* } 1868 }
 | ||||
|  |  | |||
|  | @ -0,0 +1,67 @@ | |||
| // { dg-options "-std=gnu++11" }
 | ||||
| // { dg-do compile }
 | ||||
| 
 | ||||
| // Copyright (C) 2015 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
 | ||||
| // <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| #include <type_traits> | ||||
| 
 | ||||
| template<typename T, typename I0, typename... I> | ||||
| struct smallest_rank | ||||
| : std::conditional< sizeof(T) == sizeof(I0), | ||||
|                     I0, | ||||
|                     typename smallest_rank<T, I...>::type > | ||||
| { }; | ||||
| 
 | ||||
| template<typename T, typename I0> | ||||
| struct smallest_rank<T, I0> | ||||
| { using type = I0; }; | ||||
| 
 | ||||
| template<typename T> | ||||
| using smallest_rank_t | ||||
|   = typename smallest_rank<typename std::remove_cv<T>::type, | ||||
|                            unsigned char, unsigned short, unsigned int, | ||||
|                            unsigned long, unsigned long long>::type; | ||||
| 
 | ||||
| using std::make_unsigned; | ||||
| using std::is_same; | ||||
| 
 | ||||
| enum E1 : char { }; | ||||
| using I1 = smallest_rank_t<E1>; | ||||
| static_assert(is_same<make_unsigned<E1>::type, I1>::value, ""); | ||||
| static_assert(is_same<make_unsigned<E1 const>::type, I1 const>::value, ""); | ||||
| 
 | ||||
| enum E2 : short { }; | ||||
| using I2 = smallest_rank_t<E2>; | ||||
| static_assert(is_same<make_unsigned<E2>::type, I2>::value, ""); | ||||
| static_assert(is_same<make_unsigned<E2 const>::type, I2 const>::value, ""); | ||||
| 
 | ||||
| enum E3 : int { }; | ||||
| using I3 = smallest_rank_t<E3>; | ||||
| static_assert(is_same<make_unsigned<E3>::type, I3>::value, ""); | ||||
| static_assert(is_same<make_unsigned<E3 const>::type, I3 const>::value, ""); | ||||
| 
 | ||||
| enum E4 : long { }; | ||||
| using I4 = smallest_rank_t<E4>; | ||||
| static_assert(is_same<make_unsigned<E4>::type, I4>::value, ""); | ||||
| static_assert(is_same<make_unsigned<E4 const>::type, I4 const>::value, ""); | ||||
| 
 | ||||
| // PI libstdc++/60333
 | ||||
| enum E5 : long long { }; | ||||
| using I5 = smallest_rank_t<E5>; | ||||
| static_assert(is_same<make_unsigned<E5>::type, I5>::value, ""); | ||||
| static_assert(is_same<make_unsigned<E5 const>::type, I5 const>::value, ""); | ||||
|  | @ -48,5 +48,5 @@ void test01() | |||
| // { dg-error "required from here" "" { target *-*-* } 40 }
 | ||||
| // { dg-error "required from here" "" { target *-*-* } 42 }
 | ||||
| 
 | ||||
| // { dg-error "invalid use of incomplete type" "" { target *-*-* } 1757 }
 | ||||
| // { dg-error "invalid use of incomplete type" "" { target *-*-* } 1764 }
 | ||||
| // { dg-error "declaration of" "" { target *-*-* } 1721 }
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Jonathan Wakely
						Jonathan Wakely