Andrey Chernov
2016-Jul-14 01:00 UTC
svn commit: r302601 - in head/sys: arm/include arm64/include [clang 3.8.0: powerpc has odd mix of signed wchar_t and unsigned char]
On 13.07.2016 11:53, Mark Millard wrote:> [The below does note that TARGET=powerpc has a mix of signed wchar_t and unsigned char types and most architectures have both being signed types.]POSIX says nothing about wchar_t and char should be the same (un)signed. It is arm ABI docs may say so only. They are different entities differently encoded and cross assigning between wchar_t and char is not recommended.> > On 2016-Jul-11, at 8:57 PM, Andrey Chernov <ache at freebsd.org> wrote: > >> On 12.07.2016 5:44, Mark Millard wrote: >>> My understanding of the criteria for __WCHAR_MIN and __WCHAR_MAX: >>> >>> A) __WCHAR_MIN and __WCHAR_MAX: same type as the integer promotion of >>> ___wchar_t (if that is distinct). >>> B) __WCHAR_MIN is the low value for ___wchar_t as an integer type; not >>> necessarily a valid char value >>> C) __WCHAR_MAX is the high value for ___wchar_t as an integer type; not >>> necessarily a valid char value >> >> It seems you are right about "not a valid char value", I'll back this >> change out. >> >>> As far as I know arm FreeBSD uses unsigned character types (of whatever >>> width). >> >> Probably it should be unsigned for other architectures too, clang does >> not generate negative values with L'<char>' literals and locale use only >> positive values too. > > Looking around: > > # grep -i wchar sys/*/include/_types.h > sys/arm/include/_types.h:typedef unsigned int ___wchar_t; > sys/arm/include/_types.h:#define __WCHAR_MIN 0 /* min value for a wchar_t */ > sys/arm/include/_types.h:#define __WCHAR_MAX __UINT_MAX /* max value for a wchar_t */ > sys/arm64/include/_types.h:typedef unsigned int ___wchar_t; > sys/arm64/include/_types.h:#define __WCHAR_MIN 0 /* min value for a wchar_t */ > sys/arm64/include/_types.h:#define __WCHAR_MAX __UINT_MAX /* max value for a wchar_t */ > sys/mips/include/_types.h:typedef int ___wchar_t; > sys/mips/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/mips/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/powerpc/include/_types.h:typedef int ___wchar_t; > sys/powerpc/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/powerpc/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/riscv/include/_types.h:typedef int ___wchar_t; > sys/riscv/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/riscv/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/sparc64/include/_types.h:typedef int ___wchar_t; > sys/sparc64/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/sparc64/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/x86/include/_types.h:typedef int ___wchar_t; > sys/x86/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/x86/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > > So only arm and arm64 have unsigned wchar_t types. > > [NOTE: __CHAR16_TYPE__ and __CHAR32_TYPE__ are always unsigned: in C++11 terms char16_t is like std::uint_least16_t and char32_t is like std::uint_least32_t despite being distinct types. So __CHAR16_TYPE__ and __CHAR32_TYPE__ are ignored below.] > > The clang 3.8.0 compiler output has an odd mix for TARGET_ARCH=powerpc and TARGET_ARCH=powerpc64 . . . > > armv6 has unsigned types for both char and __WCHAR_TYPE__. > aarch64 has unsigned types for both char and __WCHAR_TYPE__. > powerpc has unsigned for char but signed for __WCHAR_TYPE__. > powerpc64 has unsigned for char but signed for __WCHAR_TYPE__. > amd64 has signed types for both char and __WCHAR_TYPE__. > i386 has signed types for both char and __WCHAR_TYPE__. > mips has signed types for both char and __WCHAR_TYPE__. > sparc64 has signed types for both char and __WCHAR_TYPE__. > (riscv is not covered by clang as I understand) > > The details via compiler #define's. . . > > # clang --target=armv6-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 4294967295U > #define __WCHAR_TYPE__ unsigned int > #define __WCHAR_UNSIGNED__ 1 > #define __WCHAR_WIDTH__ 32 > . . . > > # clang --target=aarch64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 4294967295U > #define __WCHAR_TYPE__ unsigned int > #define __WCHAR_UNSIGNED__ 1 > #define __WCHAR_WIDTH__ 32 > . . . > > # clang --target=powerpc-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > Is powerpc wrong? > > # clang --target=powerpc64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > Is powerpc64 wrong? > > > # clang --target=amd64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > # clang --target=i386-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > > # clang --target=mips-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > # clang --target=sparc64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > > > ==> Mark Millard > markmi at dsl-only.net >
Mark Millard
2016-Jul-14 06:46 UTC
svn commit: r302601 - in head/sys: arm/include arm64/include [clang 3.8.0: powerpc int instead of 32-bit SYSVR4's long and 64-bit ELF V2 long]
On 2016-Jul-13, at 6:00 PM, Andrey Chernov <ache at freebsd.org> wrote:> On 13.07.2016 11:53, Mark Millard wrote: >> [The below does note that TARGET=powerpc has a mix of signed wchar_t and unsigned char types and most architectures have both being signed types.] > > POSIX says nothing about wchar_t and char should be the same (un)signed. > It is arm ABI docs may say so only. They are different entities > differently encoded and cross assigning between wchar_t and char is not > recommended.[My "odd" would better have been the longer phrase "unusual for FreeBSD" for the signed type mismatch point.] C11 (9899:2011[2012]) and C++11 (14882:2011(E)) agree with your POSIX note: no constraint to have the same signed type status as char. But when I then looked at the "System V Application Binary Interface PowerpC Processor Supplement" (1995-Sept SunSoft document) that I believe FreeBSD uses for powerpc (32-bit only: TARGET_ARCH=powerpc) it has: typedef long wchar_t; as part of: Figure 6-39 <stddef.h> (page labeled 6-38). While agreeing about the signed-type status for wchar_t this does not agree with FreeBSD 11.0's use of int as the type: sys/powerpc/include/_types.h:typedef int ___wchar_t; sys/powerpc/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ sys/powerpc/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ # clang --target=powerpc-freebsd11 -std=c99 -E -dM - < /dev/null | more . . . #define __WCHAR_MAX__ 2147483647 #define __WCHAR_TYPE__ int #define __WCHAR_WIDTH__ 32 . . . I'm not as sure of which document is official for TARGET_ARCH=powerpc64 but using "Power Architecture 64-bit ELF V2 ABI Specification" (Open POWER ABI for Linux Supplement) as an example of what likely is common for that context: 5.1.3 Types Defined in Standard header lists: typedef long wchar_t; which again does not agree with FreeBSD 11.0's use of int as the type: # clang --target=powerpc64-freebsd11 -std=c99 -E -dM - < /dev/null | more . . . #define __WCHAR_MAX__ 2147483647 #define __WCHAR_TYPE__ int #define __WCHAR_WIDTH__ 32 . . . ==Mark Millard markmi at dsl-only.net> > On 2016-Jul-11, at 8:57 PM, Andrey Chernov <ache at freebsd.org> wrote: > >> On 12.07.2016 5:44, Mark Millard wrote: >>> My understanding of the criteria for __WCHAR_MIN and __WCHAR_MAX: >>> >>> A) __WCHAR_MIN and __WCHAR_MAX: same type as the integer promotion of >>> ___wchar_t (if that is distinct). >>> B) __WCHAR_MIN is the low value for ___wchar_t as an integer type; not >>> necessarily a valid char value >>> C) __WCHAR_MAX is the high value for ___wchar_t as an integer type; not >>> necessarily a valid char value >> >> It seems you are right about "not a valid char value", I'll back this >> change out. >> >>> As far as I know arm FreeBSD uses unsigned character types (of whatever >>> width). >> >> Probably it should be unsigned for other architectures too, clang does >> not generate negative values with L'<char>' literals and locale use only >> positive values too. > > Looking around: > > # grep -i wchar sys/*/include/_types.h > sys/arm/include/_types.h:typedef unsigned int ___wchar_t; > sys/arm/include/_types.h:#define __WCHAR_MIN 0 /* min value for a wchar_t */ > sys/arm/include/_types.h:#define __WCHAR_MAX __UINT_MAX /* max value for a wchar_t */ > sys/arm64/include/_types.h:typedef unsigned int ___wchar_t; > sys/arm64/include/_types.h:#define __WCHAR_MIN 0 /* min value for a wchar_t */ > sys/arm64/include/_types.h:#define __WCHAR_MAX __UINT_MAX /* max value for a wchar_t */ > sys/mips/include/_types.h:typedef int ___wchar_t; > sys/mips/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/mips/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/powerpc/include/_types.h:typedef int ___wchar_t; > sys/powerpc/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/powerpc/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/riscv/include/_types.h:typedef int ___wchar_t; > sys/riscv/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/riscv/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/sparc64/include/_types.h:typedef int ___wchar_t; > sys/sparc64/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/sparc64/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > sys/x86/include/_types.h:typedef int ___wchar_t; > sys/x86/include/_types.h:#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ > sys/x86/include/_types.h:#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ > > So only arm and arm64 have unsigned wchar_t types. > > [NOTE: __CHAR16_TYPE__ and __CHAR32_TYPE__ are always unsigned: in C++11 terms char16_t is like std::uint_least16_t and char32_t is like std::uint_least32_t despite being distinct types. So __CHAR16_TYPE__ and __CHAR32_TYPE__ are ignored below.] > > The clang 3.8.0 compiler output has an odd mix for TARGET_ARCH=powerpc and TARGET_ARCH=powerpc64 . . . > > armv6 has unsigned types for both char and __WCHAR_TYPE__. > aarch64 has unsigned types for both char and __WCHAR_TYPE__. > powerpc has unsigned for char but signed for __WCHAR_TYPE__. > powerpc64 has unsigned for char but signed for __WCHAR_TYPE__. > amd64 has signed types for both char and __WCHAR_TYPE__. > i386 has signed types for both char and __WCHAR_TYPE__. > mips has signed types for both char and __WCHAR_TYPE__. > sparc64 has signed types for both char and __WCHAR_TYPE__. > (riscv is not covered by clang as I understand) > > The details via compiler #define's. . . > > # clang --target=armv6-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 4294967295U > #define __WCHAR_TYPE__ unsigned int > #define __WCHAR_UNSIGNED__ 1 > #define __WCHAR_WIDTH__ 32 > . . . > > # clang --target=aarch64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 4294967295U > #define __WCHAR_TYPE__ unsigned int > #define __WCHAR_UNSIGNED__ 1 > #define __WCHAR_WIDTH__ 32 > . . . > > # clang --target=powerpc-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > Is powerpc wrong? > > # clang --target=powerpc64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > #define __CHAR_UNSIGNED__ 1 > . . . > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > Is powerpc64 wrong? > > > # clang --target=amd64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > # clang --target=i386-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > > # clang --target=mips-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > # clang --target=sparc64-freebsd11 -std=c99 -E -dM - < /dev/null | more > . . . > #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ > . . . > #define __CHAR_BIT__ 8 > . . . (note the lack of __CHAR_UNSIGNED__) . . . > > #define __WCHAR_MAX__ 2147483647 > #define __WCHAR_TYPE__ int > #define __WCHAR_WIDTH__ 32 > . . . (note the lack of __WCHAR_UNSIGNED__) . . . > > > > ==> Mark Millard > markmi at dsl-only.net >