Date: Fri, 18 Jan 2013 20:11:33 -0500 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Make bits/wchar.h correct for all architectures (bug 15036) (fwd) Hi all, I think the same issues apply to musl, and the solution seems very elegant. Maybe we can apply the same thing. What do you think? Rich ----- Forwarded message from "Joseph S. Myers" <joseph@...esourcery.com> ----- Comment: DKIM? See http://www.dkim.org Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys Date: Fri, 18 Jan 2013 22:41:04 +0000 From: "Joseph S. Myers" <joseph@...esourcery.com> To: libc-alpha@...rceware.org Subject: Make bits/wchar.h correct for all architectures (bug 15036) Message-ID: <Pine.LNX.4.64.1301182239430.7560@...raph.polyomino.org.uk> Mailing-List: contact libc-alpha-help@...rceware.org; run by ezmlm Delivered-To: mailing list libc-alpha@...rceware.org The standard headers stdint.h and wchar.h define macros WCHAR_MIN and WCHAR_MAX; they are defined in glibc via bits/wchar.h. These are the limits of wchar_t (as an integer type; not necessarily valid character values) and must have the same type as results from applying the integer promotions to an object of type wchar_t, as well as being integer constant expressions usable in #if directives. The generic bits/wchar.h has definitions that are only correct when wchar_t is int. x86, but no other architecture, has its own version of the header to allow for the type being long rather than int on 32-bit x86. This leaves the values incorrect when the type is unsigned int (ARM, AArch64) and the type incorrect but the values correct when it is long (m68k, hppa, 32-bit powerpc, sh, I think based on examination of GCC headers). I've filed by 15036 for this issue. Since GCC 3.3, a macro __WCHAR_MAX__ has been predefined by GCC, and since 4.5 a macro __WCHAR_MIN__ has been predefined as well. These deal with getting the type and value right in all cases, and so it is natural to use them in bits/wchar.h when available. When those predefined macros are not available, it is still possible to give definitions that are correct for all systems supported by glibc. For all such systems, int is 32-bit, and so is wchar_t. Now it is possible to determine in the preprocessor whether wchar_t is signed or unsigned by testing "L'\0' - 1 > 0", and knowing that, we know what the correct limiting values of 32-bit wchar_t are, and can ensure the type is correct by adding L'\0'. This patch implements such logic to determine the expansions of these macros (using the GCC macros where available, and logic that's correct for 32-bit int and wchar_t otherwise), so eliminating the x86-specific version of this header. (The construct (L'\0' + 0), rather than just L'\0', for the MIN value in the unsigned case, is to ensure that for C++ the type is still the promoted version of wchar_t, rather than wchar_t itself which is a distinct type in C++. The reason for (0xffffffffu + L'\0') rather than just (L'\0' - 1) as the MAX value in the unsigned case is that (L'\0' - 1) would have the wrong value in preprocessor expressions, UINTMAX_MAX, because all unsigned types are treated as uintmax_t in such expressions.) Tested x86_64 and x86. 2013-01-18 Joseph Myers <joseph@...esourcery.com> [BZ #15036] * bits/wchar.h (__WCHAR_MAX): Define based on __WCHAR_MAX__, or based on [L'\0' - 1 > 0] if [!__WCHAR_MAX__]. (__WCHAR_MIN): Likewise, using __WCHAR_MIN__. * sysdeps/unix/sysv/linux/x86/bits/wchar.h: Remove. diff --git a/bits/wchar.h b/bits/wchar.h index eb07151..2bbd93c 100644 --- a/bits/wchar.h +++ b/bits/wchar.h @@ -19,7 +19,20 @@ #ifndef _BITS_WCHAR_H #define _BITS_WCHAR_H 1 -#define __WCHAR_MIN (-2147483647 - 1) -#define __WCHAR_MAX (2147483647) +#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/sysdeps/unix/sysv/linux/x86/bits/wchar.h b/sysdeps/unix/sysv/linux/x86/bits/wchar.h deleted file mode 100644 index 16b8b77..0000000 --- a/sysdeps/unix/sysv/linux/x86/bits/wchar.h +++ /dev/null @@ -1,32 +0,0 @@ -/* wchar_t type related definitions. i386/x86-64 version. - Copyright (C) 2000-2013 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 - -#include <bits/wordsize.h> - -#if __WORDSIZE == 64 -# define __WCHAR_MIN (-2147483647 - 1) -# define __WCHAR_MAX (2147483647) -#else -# define __WCHAR_MIN (-2147483647l - 1l) -# define __WCHAR_MAX (2147483647l) -#endif - -#endif /* bits/wchar.h */ -- Joseph S. Myers joseph@...esourcery.com ----- End forwarded message -----
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.