diff mbox

libstdc++/60326 make_signed/make_unsigned for wide char types

Message ID 20140515123057.GA26271@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely May 15, 2014, 12:30 p.m. UTC
We are missing specializations for wchar_t, char16_t and char32_t.

The preprocessor condition I've added at the top of <type_traits> is
to avoid needing to #include <cstdint>, which drops names in the
global namespace. GCC defines __UINT_LEAST16_TYPE__ and
__UINT_LEAST32_TYPE__ so we can use them, but other compilers may not
(Clang doesn't) so just #include <cstdint> and accept that <stdint.h>
might put its contents in the global namespace.

Tested x86_64-linux, committed to trunk. I'd like to put this on the
branch for 4.9.1 too, but will wait a while.
diff mbox

Patch

commit e1804a737ee8f12f2e1e4fb93693eb96bff6e8af
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue May 13 16:04:37 2014 +0100

    	PR libstdc++/60326
    	* include/std/type_traits (__make_unsigned, __make_signed): Define
    	specializations for wchar_t, char16_t and char32_t.
    	* testsuite/20_util/make_signed/requirements/typedefs-4.cc: New.
    	* testsuite/20_util/make_unsigned/requirements/typedefs-1.cc: Correct
    	test for make_unsigned<volatile wchar_t>.
    	* testsuite/20_util/make_unsigned/requirements/typedefs-2.cc:
    	Likewise.
    	* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
    	line number.
    	* testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
    	Likewise.
    	* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
    	Likewise.

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 4b434a6..0eacd36 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -41,6 +41,15 @@  namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+# if defined (__UINT_LEAST16_TYPE__) && defined(__UINT_LEAST32_TYPE__)
+  typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+  typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+# else
+#  include <cstdint>
+# endif
+#endif
+
   /**
    * @defgroup metaprogramming Metaprogramming
    * @ingroup utilities
@@ -1583,6 +1592,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __make_unsigned<long long>
     { typedef unsigned long long __type; };
 
+#if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__)
+  template<>
+    struct __make_unsigned<wchar_t> : __make_unsigned<__WCHAR_TYPE__>
+    { };
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
   template<>
     struct __make_unsigned<__int128>
@@ -1665,6 +1680,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __make_signed<unsigned long long>
     { typedef signed long long __type; };
 
+#if defined(_GLIBCXX_USE_WCHAR_T) && defined(__WCHAR_UNSIGNED__)
+  template<>
+    struct __make_signed<wchar_t> : __make_signed<__WCHAR_TYPE__>
+    { };
+#endif
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+  template<>
+    struct __make_signed<char16_t> : __make_signed<uint_least16_t>
+    { };
+  template<>
+    struct __make_signed<char32_t> : __make_signed<uint_least32_t>
+    { };
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
   template<>
     struct __make_signed<unsigned __int128>
diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
index a744d83..6be3af0 100644
--- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
@@ -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 *-*-* } 2003 }
+// { dg-error "static assertion failed" "" { target *-*-* } 2033 }
 
 #include <utility>
 
diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-4.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-4.cc
new file mode 100644
index 0000000..4950e54
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-4.cc
@@ -0,0 +1,33 @@ 
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2014 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>
+
+// libstdc++/60326
+
+using namespace std;
+#ifdef _GLIBCXX_USE_WCHAR_T
+using wchar_signed = make_signed<wchar_t>::type;
+using wchar_unsigned = make_unsigned<wchar_t>::type;
+static_assert( !is_same<wchar_signed, wchar_unsigned>::value, "wchar_t" );
+#endif
+static_assert( is_signed<make_signed<char16_t>::type>::value, "char16_t");
+static_assert( is_signed<make_signed<char32_t>::type>::value, "char32_t");
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 9f155ea..77f8bb3 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
@@ -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 *-*-* } 1714 }
-// { dg-error "declaration of" "" { target *-*-* } 1678 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1744 }
+// { dg-error "declaration of" "" { target *-*-* } 1708 }
diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-1.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-1.cc
index f07cf4a..a893ede 100644
--- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-1.cc
+++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-1.cc
@@ -49,7 +49,7 @@  void test01()
 
 #ifdef _GLIBCXX_USE_WCHAR_T
   typedef make_unsigned<volatile wchar_t>::type  	test23_type;
-  static_assert(is_same<test23_type, volatile wchar_t>::value, "");
+  static_assert(is_same<test23_type, volatile unsigned wchar_t>::value, "");
 #endif
 
   // Chapter 48, chapter 20. Smallest rank such that new unsigned type
diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
index 8997fb7..637b0c7 100644
--- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
+++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
@@ -50,7 +50,7 @@  void test01()
 
 #ifdef _GLIBCXX_USE_WCHAR_T
   typedef make_unsigned<volatile wchar_t>::type  	test23_type;
-  static_assert(is_same<test23_type, volatile wchar_t>::value, "");
+  static_assert(is_same<test23_type, volatile unsigned wchar_t>::value, "");
 #endif
 
   typedef make_unsigned<test_enum>::type  	  test24_type;
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 57a5c61..48ee225 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
@@ -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 *-*-* } 1632 }
-// { dg-error "declaration of" "" { target *-*-* } 1596 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1647 }
+// { dg-error "declaration of" "" { target *-*-* } 1611 }