Browse Source

[PATCH] libc/sysdeps/linux/common/bits/wchar.h: resync with glibc, fix build issue with gcc 12

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.ramirez@bootlin.com>
With-some-useful-help-from: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Waldemar Brodkorb 10 months ago
parent
commit
2c46c4ed23
2 changed files with 28 additions and 29 deletions
  1. 28 4
      libc/sysdeps/linux/common/bits/wchar.h
  2. 0 25
      libc/sysdeps/linux/i386/bits/wchar.h

+ 28 - 4
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-2023 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 */

+ 0 - 25
libc/sysdeps/linux/i386/bits/wchar.h

@@ -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 */