Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Jul 2016 04:00:24 +0300
From:      Andrey Chernov <ache@freebsd.org>
To:        Mark Millard <markmi@dsl-only.net>
Cc:        svn-src-head@freebsd.org, FreeBSD Current <freebsd-current@freebsd.org>, freebsd-stable@freebsd.org, freebsd-arm <freebsd-arm@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, Bruce Evans <brde@optusnet.com.au>, FreeBSD Toolchain <freebsd-toolchain@freebsd.org>
Subject:   Re: 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]
Message-ID:  <a3f33812-1780-024e-4638-994c56e45c42@freebsd.org>
In-Reply-To: <38CF2C28-3BD1-4D09-939F-4DD0C2E8B58F@dsl-only.net>
References:  <46153340-D2F4-48BD-B738-4792BC25FA3F@dsl-only.net> <b4d1b3d9-9577-3f89-c13e-8c46d1ddee95@freebsd.org> <38CF2C28-3BD1-4D09-939F-4DD0C2E8B58F@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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
> 




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?a3f33812-1780-024e-4638-994c56e45c42>