honor __WCHAR_TYPE__ on archs with legacy long definition of wchar_t
authorRich Felker <dalias@aerifal.cx>
Sun, 8 Sep 2019 21:33:48 +0000 (17:33 -0400)
committerRich Felker <dalias@aerifal.cx>
Sun, 8 Sep 2019 21:33:48 +0000 (17:33 -0400)
historically, a number of 32-bit archs used long rather than int for
wchar_t, for no good reason. GCC still uses the historical types, but
clang replaced them all with int, and it seems PCC uses int too.
mismatching the compiler's type for wchar_t is not an option due to
wide string literals.

note that the mismatch does not affect C++ ABI since wchar_t is its
own builtin type/keyword in C++, distinct from both int and long, not
a typedef.

i386 already worked around this by honoring __WCHAR_TYPE__ if defined
by the compiler, and only using the official legacy ABI type if not.
add the same to the other affected archs.

it might make sense at some point to switch to using int as the
default if __WCHAR_TYPE__ is not defined, if the expectations is that
new compilers will treat int as the correct choice, but it's unlikely
that the case where __WCHAR_TYPE__ is undefined will ever be used
anyway. I actually wanted to move the definition of wchar_t to the
top-level shared alltypes.h.in, using __WCHAR_TYPE__ and falling back
to int if not defined, but that can't be done without assuming all
compilers define __WCHAR_TYPE__ thanks to some pathological archs
where the ABI has wchar_t as an unsigned type.

arch/m68k/bits/alltypes.h.in
arch/powerpc/bits/alltypes.h.in
arch/sh/bits/alltypes.h.in
arch/x32/bits/alltypes.h.in

index a4a8141fe2ae5ca523c18bdf96a2af2ff84c713a..bd37a6318da7e405f8bef956942c9d6a265fe481 100644 (file)
@@ -6,8 +6,12 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF __builtin_va_list __isoc_va_list;
 
 #ifndef __cplusplus
+#ifdef __WCHAR_TYPE__
+TYPEDEF __WCHAR_TYPE__ wchar_t;
+#else
 TYPEDEF long wchar_t;
 #endif
+#endif
 
 #if __mcffpu__
 TYPEDEF float float_t;
index 37f27d6f4d58479f60a3dc814421b86869ea42a9..8e687ef16dd3d24d64f4e7fd7ba91cee2b4677c7 100644 (file)
@@ -6,8 +6,12 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF __builtin_va_list __isoc_va_list;
 
 #ifndef __cplusplus
+#ifdef __WCHAR_TYPE__
+TYPEDEF __WCHAR_TYPE__ wchar_t;
+#else
 TYPEDEF long wchar_t;
 #endif
+#endif
 
 TYPEDEF float float_t;
 TYPEDEF double double_t;
index 37f27d6f4d58479f60a3dc814421b86869ea42a9..8e687ef16dd3d24d64f4e7fd7ba91cee2b4677c7 100644 (file)
@@ -6,8 +6,12 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF __builtin_va_list __isoc_va_list;
 
 #ifndef __cplusplus
+#ifdef __WCHAR_TYPE__
+TYPEDEF __WCHAR_TYPE__ wchar_t;
+#else
 TYPEDEF long wchar_t;
 #endif
+#endif
 
 TYPEDEF float float_t;
 TYPEDEF double double_t;
index 16391295bcbf5c56cc6ef0898ad1a19dfa44f290..c612eec098263b63e27386f6ff9e6ea9fd4a8f2c 100644 (file)
@@ -6,8 +6,12 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF __builtin_va_list __isoc_va_list;
 
 #ifndef __cplusplus
+#ifdef __WCHAR_TYPE__
+TYPEDEF __WCHAR_TYPE__ wchar_t;
+#else
 TYPEDEF long wchar_t;
 #endif
+#endif
 
 #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
 TYPEDEF long double float_t;