The current definition of __WCHAR_MIN and __WCHAR_MAX are only correct
when wchar_t is an int. This is not the case on ARM/AArch64 where
wchar_t is an unsigned int, or some other architectures where wchar_t
is a long.

The current incorrect definition causes a build issue for example when
building mpd, which uses boost, with gcc 12.x:

In file included from 
/home/thomas/buildroot/aarch64/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/boost/integer.hpp:20,
                 from 
/home/thomas/buildroot/aarch64/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/boost/crc.hpp:42,
                 from ../src/storage/StorageState.cxx:43:
/home/thomas/buildroot/aarch64/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/boost/integer_traits.hpp:105:69:
 error: narrowing conversion of ‘-2147483648’ from ‘int’ to ‘wchar_t’ 
[-Wnarrowing]
  105 |     public detail::integer_traits_base<wchar_t, WCHAR_MIN, WCHAR_MAX>
      |                                                                     ^

This issue was fixed in glibc in 2013, see bug report
https://sourceware.org/bugzilla/show_bug.cgi?id=15036, and upstream
commit
https://sourceware.org/git/?p=glibc.git;a=commit;h=052aff95782fefe9c63566471063e8b20836bfb8.

Since the i386-specific definition of __WCHAR_MIN and __WCHAR_MAX was
also removed at the same time in glibc, we do the same as part of this
commit.

Reported-by: Clément Ramirez <clement.rami...@bootlin.com>
With-some-useful-help-from: Paul Kocialkowski <paul.kocialkow...@bootlin.com>
Signed-off-by: Thomas Petazzoni <thomas.petazz...@bootlin.com>
---
 libc/sysdeps/linux/common/bits/wchar.h | 32 ++++++++++++++++++++++----
 libc/sysdeps/linux/i386/bits/wchar.h   | 25 --------------------
 2 files changed, 28 insertions(+), 29 deletions(-)
 delete mode 100644 libc/sysdeps/linux/i386/bits/wchar.h

diff --git a/libc/sysdeps/linux/common/bits/wchar.h 
b/libc/sysdeps/linux/common/bits/wchar.h
index a3ff5319e..50c7ef37b 100644
--- a/libc/sysdeps/linux/common/bits/wchar.h
+++ b/libc/sysdeps/linux/common/bits/wchar.h
@@ -1,5 +1,5 @@
 /* wchar_t type related definitions.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -14,12 +14,36 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   <https://www.gnu.org/licenses/>.  */
 
 #ifndef _BITS_WCHAR_H
 #define _BITS_WCHAR_H  1
 
-#define __WCHAR_MIN    (-2147483647 - 1)
-#define __WCHAR_MAX    (2147483647)
+/* The fallback definitions, for when __WCHAR_MAX__ or __WCHAR_MIN__
+   are not defined, give the right value and type as long as both int
+   and wchar_t are 32-bit types.  Adding L'\0' to a constant value
+   ensures that the type is correct; it is necessary to use (L'\0' +
+   0) rather than just L'\0' so that the type in C++ is the promoted
+   version of wchar_t rather than the distinct wchar_t type itself.
+   Because wchar_t in preprocessor #if expressions is treated as
+   intmax_t or uintmax_t, the expression (L'\0' - 1) would have the
+   wrong value for WCHAR_MAX in such expressions and so cannot be used
+   to define __WCHAR_MAX in the unsigned case.  */
+
+#ifdef __WCHAR_MAX__
+# define __WCHAR_MAX   __WCHAR_MAX__
+#elif L'\0' - 1 > 0
+# define __WCHAR_MAX   (0xffffffffu + L'\0')
+#else
+# define __WCHAR_MAX   (0x7fffffff + L'\0')
+#endif
+
+#ifdef __WCHAR_MIN__
+# define __WCHAR_MIN   __WCHAR_MIN__
+#elif L'\0' - 1 > 0
+# define __WCHAR_MIN   (L'\0' + 0)
+#else
+# define __WCHAR_MIN   (-__WCHAR_MAX - 1)
+#endif
 
 #endif /* bits/wchar.h */
diff --git a/libc/sysdeps/linux/i386/bits/wchar.h 
b/libc/sysdeps/linux/i386/bits/wchar.h
deleted file mode 100644
index b94fc7a3f..000000000
--- a/libc/sysdeps/linux/i386/bits/wchar.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* wchar_t type related definitions.
-   Copyright (C) 2000 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _BITS_WCHAR_H
-#define _BITS_WCHAR_H  1
-
-#define __WCHAR_MIN    (-2147483647l - 1l)
-#define __WCHAR_MAX    (2147483647l)
-
-#endif /* bits/wchar.h */
-- 
2.41.0

_______________________________________________
devel mailing list -- devel@uclibc-ng.org
To unsubscribe send an email to devel-le...@uclibc-ng.org

Reply via email to