On targets where wchar_t is unsigned we get warnings during the
libstdc++ build:

ctype_members.cc: In member function ‘virtual char 
std::ctype<wchar_t>::do_narrow(wchar_t, char) const’:
ctype_members.cc:224:14: warning: comparison of unsigned expression in ‘>= 0’ 
is always true [-Wtype-limits]
  224 |     if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
      |         ~~~~~^~~~
ctype_members.cc: In member function ‘virtual const wchar_t* 
std::ctype<wchar_t>::do_narrow(const wchar_t*, const wchar_t*, char, char*) 
const’:
ctype_members.cc:247:21: warning: comparison of unsigned expression in ‘>= 0’ 
is always true [-Wtype-limits]
  247 |           if (*__lo >= 0 && *__lo < 128)
      |               ~~~~~~^~~~

This introduces a helper function that converts the wchar_t to an
unsigned type and then does the comparison. This means the comparison is
not target-dependent, and there's no more warning.

libstdc++-v3/ChangeLog:

        * config/locale/gnu/ctype_members.cc (use_table): New function.
        (ctype<wchar_t>::do_narrow): Use use_table.
---

Tested x86_64-linux and aarch64-linux.

 libstdc++-v3/config/locale/gnu/ctype_members.cc | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/config/locale/gnu/ctype_members.cc 
b/libstdc++-v3/config/locale/gnu/ctype_members.cc
index 183babb6c3f6..b34446a61ee1 100644
--- a/libstdc++-v3/config/locale/gnu/ctype_members.cc
+++ b/libstdc++-v3/config/locale/gnu/ctype_members.cc
@@ -217,11 +217,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __hi;
   }
 
+  // True if c can be looked up in _M_narrow.
+  [[gnu::always_inline]]
+  static inline bool
+  use_table(wchar_t c)
+  {
+    using U = std::make_unsigned<wchar_t>::type;
+    return U(c) < 128;
+  }
+
   char
   ctype<wchar_t>::
   do_narrow(wchar_t __wc, char __dfault) const
   {
-    if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
+    if (use_table(__wc) && _M_narrow_ok)
       return _M_narrow[__wc];
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
     __c_locale __old = __uselocale(_M_c_locale_ctype);
@@ -244,7 +253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     if (_M_narrow_ok)
       while (__lo < __hi)
        {
-         if (*__lo >= 0 && *__lo < 128)
+         if (use_table(*__lo))
            *__dest = _M_narrow[*__lo];
          else
            {
-- 
2.52.0

Reply via email to