[v4,2/3] stdlib: Implement mbrtoc8(), c8rtomb(), and the char8_t typedef.
Checks
Context |
Check |
Description |
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
Commit Message
This change provides implementations for the mbrtoc8 and c8rtomb
functions adopted for C++20 via WG21 P0482R6 and for C2X via WG14
N2653. It also provides the char8_t typedef from WG14 N2653.
The mbrtoc8 and c8rtomb functions are declared in uchar.h in C2X
mode or when the _GNU_SOURCE macro or C++20 __cpp_char8_t feature
test macro is defined.
The char8_t typedef is declared in uchar.h in C2X mode or when the
_GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature
test macro is not defined (if __cpp_char8_t is defined, then char8_t
is a builtin type).
---
NEWS | 9 ++
sysdeps/mach/hurd/i386/libc.abilist | 2 +
sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 +
sysdeps/unix/sysv/linux/arc/libc.abilist | 2 +
sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 +
sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 +
sysdeps/unix/sysv/linux/csky/libc.abilist | 2 +
sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 +
sysdeps/unix/sysv/linux/i386/libc.abilist | 2 +
sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 +
.../sysv/linux/m68k/coldfire/libc.abilist | 2 +
.../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 +
.../sysv/linux/microblaze/be/libc.abilist | 2 +
.../sysv/linux/microblaze/le/libc.abilist | 2 +
.../sysv/linux/mips/mips32/fpu/libc.abilist | 2 +
.../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 +
.../sysv/linux/mips/mips64/n32/libc.abilist | 2 +
.../sysv/linux/mips/mips64/n64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 +
sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 +
.../linux/powerpc/powerpc32/fpu/libc.abilist | 2 +
.../powerpc/powerpc32/nofpu/libc.abilist | 2 +
.../linux/powerpc/powerpc64/be/libc.abilist | 2 +
.../linux/powerpc/powerpc64/le/libc.abilist | 2 +
.../unix/sysv/linux/riscv/rv32/libc.abilist | 2 +
.../unix/sysv/linux/riscv/rv64/libc.abilist | 2 +
.../unix/sysv/linux/s390/s390-32/libc.abilist | 2 +
.../unix/sysv/linux/s390/s390-64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 +
sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 +
.../sysv/linux/sparc/sparc32/libc.abilist | 2 +
.../sysv/linux/sparc/sparc64/libc.abilist | 2 +
.../unix/sysv/linux/x86_64/64/libc.abilist | 2 +
.../unix/sysv/linux/x86_64/x32/libc.abilist | 2 +
wcsmbs/Makefile | 2 +-
wcsmbs/Versions | 3 +
wcsmbs/c8rtomb.c | 132 ++++++++++++++++++
wcsmbs/mbrtoc8.c | 126 +++++++++++++++++
wcsmbs/uchar.h | 21 +++
40 files changed, 360 insertions(+), 1 deletion(-)
create mode 100644 wcsmbs/c8rtomb.c
create mode 100644 wcsmbs/mbrtoc8.c
Comments
> On 30 Jun 2022, at 09:52, Tom Honermann via Libc-alpha <libc-alpha@sourceware.org> wrote:
>
> This change provides implementations for the mbrtoc8 and c8rtomb
> functions adopted for C++20 via WG21 P0482R6 and for C2X via WG14
> N2653. It also provides the char8_t typedef from WG14 N2653.
>
> The mbrtoc8 and c8rtomb functions are declared in uchar.h in C2X
> mode or when the _GNU_SOURCE macro or C++20 __cpp_char8_t feature
> test macro is defined.
>
> The char8_t typedef is declared in uchar.h in C2X mode or when the
> _GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature
> test macro is not defined (if __cpp_char8_t is defined, then char8_t
> is a builtin type).
LGTM with a minor nit below.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> NEWS | 9 ++
> sysdeps/mach/hurd/i386/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/arc/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/csky/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/i386/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 +
> .../sysv/linux/m68k/coldfire/libc.abilist | 2 +
> .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 +
> .../sysv/linux/microblaze/be/libc.abilist | 2 +
> .../sysv/linux/microblaze/le/libc.abilist | 2 +
> .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 +
> .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 +
> .../sysv/linux/mips/mips64/n32/libc.abilist | 2 +
> .../sysv/linux/mips/mips64/n64/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 +
> .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 +
> .../powerpc/powerpc32/nofpu/libc.abilist | 2 +
> .../linux/powerpc/powerpc64/be/libc.abilist | 2 +
> .../linux/powerpc/powerpc64/le/libc.abilist | 2 +
> .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 +
> .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 +
> .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 +
> .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 +
> .../sysv/linux/sparc/sparc32/libc.abilist | 2 +
> .../sysv/linux/sparc/sparc64/libc.abilist | 2 +
> .../unix/sysv/linux/x86_64/64/libc.abilist | 2 +
> .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 +
> wcsmbs/Makefile | 2 +-
> wcsmbs/Versions | 3 +
> wcsmbs/c8rtomb.c | 132 ++++++++++++++++++
> wcsmbs/mbrtoc8.c | 126 +++++++++++++++++
> wcsmbs/uchar.h | 21 +++
> 40 files changed, 360 insertions(+), 1 deletion(-)
> create mode 100644 wcsmbs/c8rtomb.c
> create mode 100644 wcsmbs/mbrtoc8.c
>
> diff --git a/NEWS b/NEWS
> index b0a3d7e512..94243e2170 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -46,6 +46,15 @@ Major new features:
> to more flexibly configure and operate on filesystem mounts. The new
> mount APIs are specifically designed to work with namespaces.
>
> +* Support for the mbrtoc8 and c8rtomb multibyte/UTF-8 character conversion
> + functions has been added per the ISO C2X N2653 and C++20 P0482R6 proposals.
> + Support for the char8_t typedef has been added per the ISO C2X N2653
> + proposal. The functions are declared in uchar.h in C2X mode or when the
> + _GNU_SOURCE macro or C++20 __cpp_char8_t feature test macro is defined.
> + The char8_t typedef is declared in uchar.h in C2X mode or when the
> + _GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature test macro
> + is not defined (if __cpp_char8_t is defined, then char8_t is a builtin type).
> +
> Deprecated and removed features, and other changes affecting compatibility:
>
> * Support for prelink will be removed in the next release; this includes
> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 4dc87e9061..66fb0e28fa 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2289,6 +2289,8 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 close_range F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 8dba065b81..b3cf9fdd70 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2616,8 +2616,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 08f4750022..2a45006462 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2713,8 +2713,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index 75db763023..0ac6bba241 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -2377,8 +2377,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index fa33f317ac..bfa763906b 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -496,8 +496,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index dba2e4ce42..ffcd7ca432 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -493,8 +493,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index e6ff921c29..940777b118 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2652,8 +2652,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 8a40cece83..508efe6626 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2601,8 +2601,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index a89826049f..16b91fcee9 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2785,8 +2785,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index d1d96b7469..51b646790d 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2551,8 +2551,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 63a62f267a..ddb43651f2 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -497,8 +497,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index f68325f9bc..3db7deb4d0 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2728,8 +2728,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 247af2075c..94afb7ad0b 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2701,8 +2701,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index b0ac3f9009..5873751425 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2698,8 +2698,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index b22cd6bf2f..f296e4edb7 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2693,8 +2693,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 12fc2cce3e..1888756819 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2691,8 +2691,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index d3e96dfd43..7dfacee25b 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2699,8 +2699,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index cb58ed4db0..53e188aafe 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2602,8 +2602,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 61ad58a599..bc6a836b1b 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2740,8 +2740,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> index 1260dc4e2e..299fa67961 100644
> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> @@ -2123,8 +2123,10 @@ GLIBC_2.35 wprintf F
> GLIBC_2.35 write F
> GLIBC_2.35 writev F
> GLIBC_2.35 wscanf F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 363939762c..a5a072394d 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2755,8 +2755,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index f512ad8baf..2d26fd8639 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2788,8 +2788,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index c9bdc9859c..d9f1c593ea 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2510,8 +2510,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index f091be30bd..874f33dbcc 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2812,8 +2812,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index 7ea73f9af8..465798a56f 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -2379,8 +2379,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 333fa62714..ecc0544c05 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2579,8 +2579,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index a867467b12..3e8d00d513 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2753,8 +2753,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index dbad5b3163..a872a3d186 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2547,8 +2547,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 6f755cc173..a2938ca2be 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2608,8 +2608,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 77d936aa3c..ef318251c5 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2605,8 +2605,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 09bb4363e1..2e2fbe72e2 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2748,8 +2748,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 9df9cb6adb..e1991259cd 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2574,8 +2574,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 4829450ad0..7d0843d1d8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2525,8 +2525,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index caea228bcb..761958f768 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2631,8 +2631,10 @@ GLIBC_2.35 __memcmpeq F
> GLIBC_2.35 _dl_find_object F
> GLIBC_2.35 epoll_pwait2 F
> GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 c8rtomb F
> GLIBC_2.36 fsmount F
> GLIBC_2.36 fsopen F
> +GLIBC_2.36 mbrtoc8 F
> GLIBC_2.36 move_mount F
> GLIBC_2.36 pidfd_getfd F
> GLIBC_2.36 pidfd_open F
> diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
> index df9a85f4a9..bda281ad70 100644
> --- a/wcsmbs/Makefile
> +++ b/wcsmbs/Makefile
> @@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
> wcsmbsload mbsrtowcs_l \
> isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
> isoc99_swscanf isoc99_vswscanf \
> - mbrtoc16 c16rtomb mbrtoc32 c32rtomb
> + mbrtoc8 c8rtomb mbrtoc16 c16rtomb mbrtoc32 c32rtomb
>
> strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
> wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
> diff --git a/wcsmbs/Versions b/wcsmbs/Versions
> index 0b31c1b940..ec28acfb73 100644
> --- a/wcsmbs/Versions
> +++ b/wcsmbs/Versions
> @@ -49,4 +49,7 @@ libc {
> wcstof32; wcstof64; wcstof32x;
> wcstof32_l; wcstof64_l; wcstof32x_l;
> }
> + GLIBC_2.36 {
> + c8rtomb; mbrtoc8;
> + }
> }
> diff --git a/wcsmbs/c8rtomb.c b/wcsmbs/c8rtomb.c
> new file mode 100644
> index 0000000000..b564770eb5
> --- /dev/null
> +++ b/wcsmbs/c8rtomb.c
> @@ -0,0 +1,132 @@
> +/* UTF-8 to multibyte conversion.
> + Copyright (C) 2022 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <errno.h>
> +#include <uchar.h>
> +#include <wchar.h>
> +
> +
> +/* This is the private state used if PS is NULL. */
> +static mbstate_t state;
> +
> +size_t
> +c8rtomb (char *s, char8_t c8, mbstate_t *ps)
> +{
> + /* This implementation depends on the converter invoked by wcrtomb not
> + needing to retain state in either the top most bit of ps->__count or
> + in ps->__value between invocations. This implementation uses the
> + top most bit of ps->__count to indicate that trailing code units are
> + expected and uses ps->__value to store previously seen code units. */
> +
> + wchar_t wc;
> +
> + if (ps == NULL)
> + ps = &state;
> +
> + if (s == NULL)
> + {
> + /* if 's' is a null pointer, behave as if u8'\0' was passed as 'c8'. If
> + this occurs for an incomplete code unit sequence, then an error will
> + be reported below. */
> + c8 = u8""[0];
> + }
> +
> + if (! (ps->__count & 0x80000000))
> + {
> + /* Initial state. */
> + if ((c8 >= 0x80 && c8 <= 0xC1) || c8 >= 0xF5)
> + {
> + /* An invalid lead code unit. */
> + __set_errno (EILSEQ);
> + return -1;
> + }
> + if (c8 >= 0xC2)
> + {
> + /* A valid lead code unit. */
> + ps->__count |= 0x80000000;
> + ps->__value.__wchb[0] = c8;
> + ps->__value.__wchb[3] = 1;
> + return 0;
> + }
> + /* A single byte (ASCII) code unit. */
> + wc = c8;
> + }
> + else
> + {
> + char8_t cu1 = ps->__value.__wchb[0];
> + if (ps->__value.__wchb[3] == 1)
> + {
> + /* A single lead code unit was previously seen. */
> + if ((c8 < 0x80 || c8 > 0xBF)
> + || (cu1 == 0xE0 && c8 < 0xA0)
> + || (cu1 == 0xED && c8 > 0x9F)
> + || (cu1 == 0xF0 && c8 < 0x90)
> + || (cu1 == 0xF4 && c8 > 0x8F))
> + {
> + /* An invalid second code unit. */
> + __set_errno (EILSEQ);
> + return -1;
> + }
> + if (cu1 >= 0xE0)
> + {
> + /* A three or four code unit sequence. */
> + ps->__value.__wchb[1] = c8;
> + ++ps->__value.__wchb[3];
> + return 0;
> + }
> + wc = ((cu1 & 0x1F) << 6)
> + + (c8 & 0x3F);
> + }
> + else
> + {
> + char8_t cu2 = ps->__value.__wchb[1];
> + /* A three or four byte code unit sequence. */
> + if (c8 < 0x80 || c8 > 0xBF)
> + {
> + /* An invalid third or fourth code unit. */
> + __set_errno (EILSEQ);
> + return -1;
> + }
> + if (ps->__value.__wchb[3] == 2 && cu1 >= 0xF0)
> + {
> + /* A four code unit sequence. */
> + ps->__value.__wchb[2] = c8;
> + ++ps->__value.__wchb[3];
> + return 0;
> + }
> + if (cu1 < 0xF0)
> + {
> + wc = ((cu1 & 0x0F) << 12)
> + + ((cu2 & 0x3F) << 6)
> + + (c8 & 0x3F);
> + }
> + else
> + {
> + char8_t cu3 = ps->__value.__wchb[2];
> + wc = ((cu1 & 0x07) << 18)
> + + ((cu2 & 0x3F) << 12)
> + + ((cu3 & 0x3F) << 6)
> + + (c8 & 0x3F);
> + }
> + }
> + ps->__count &= 0x7fffffff;
> + ps->__value.__wch = 0;
> + }
> +
> + return wcrtomb (s, wc, ps);
> +}
> diff --git a/wcsmbs/mbrtoc8.c b/wcsmbs/mbrtoc8.c
> new file mode 100644
> index 0000000000..f2fab3b6a7
> --- /dev/null
> +++ b/wcsmbs/mbrtoc8.c
> @@ -0,0 +1,126 @@
> +/* Multibyte to UTF-8 conversion.
> + Copyright (C) 2022 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <assert.h>
> +#include <dlfcn.h>
> +#include <errno.h>
> +#include <gconv.h>
> +#include <uchar.h>
> +#include <wcsmbsload.h>
> +
> +#include <sysdep.h>
> +
> +#ifndef EILSEQ
> +# define EILSEQ EINVAL
> +#endif
> +
> +
> +/* This is the private state used if PS is NULL. */
> +static mbstate_t state;
> +
> +size_t
> +mbrtoc8 (char8_t *pc8, const char *s, size_t n, mbstate_t *ps)
> +{
> + /* This implementation depends on the converter invoked by mbrtowc() not
Refer to function name without ‘()’.
> + needing to retain state in either the top most bit of ps->__count or
> + in ps->__value between invocations. This implementation uses the
> + top most bit of ps->__count to indicate that trailing code units are
> + yet to be written and uses ps->__value to store those code units. */
> +
> + if (ps == NULL)
> + ps = &state;
> +
> + /* If state indicates that trailing code units are yet to be written, write
> + those first regardless of whether 's' is a null pointer. */
> + if (ps->__count & 0x80000000)
> + {
> + /* ps->__value.__wchb[3] stores the index of the next code unit to
> + write. Code units are stored in reverse order. */
> + size_t i = ps->__value.__wchb[3];
> + if (pc8 != NULL)
> + {
> + *pc8 = ps->__value.__wchb[i];
> + }
> + if (i == 0)
> + {
> + ps->__count &= 0x7fffffff;
> + ps->__value.__wch = 0;
> + }
> + else
> + --ps->__value.__wchb[3];
> + return -3;
> + }
> +
> + if (s == NULL)
> + {
> + /* if 's' is a null pointer, behave as if a null pointer was passed for
> + 'pc8', an empty string was passed for 's', and 1 passed for 'n'. */
> + pc8 = NULL;
> + s = "";
> + n = 1;
> + }
> +
> + wchar_t wc;
> + size_t result;
> +
> + result = mbrtowc (&wc, s, n, ps);
> + if (result <= n)
> + {
> + if (wc <= 0x7F)
> + {
> + if (pc8 != NULL)
> + *pc8 = wc;
> + }
> + else if (wc <= 0x7FF)
> + {
> + if (pc8 != NULL)
> + *pc8 = 0xC0 + ((wc >> 6) & 0x1F);
> + ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
> + ps->__value.__wchb[3] = 0;
> + ps->__count |= 0x80000000;
> + }
> + else if (wc <= 0xFFFF)
> + {
> + if (pc8 != NULL)
> + *pc8 = 0xE0 + ((wc >> 12) & 0x0F);
> + ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
> + ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
> + ps->__value.__wchb[3] = 1;
> + ps->__count |= 0x80000000;
> + }
> + else if (wc <= 0x10FFFF)
> + {
> + if (pc8 != NULL)
> + *pc8 = 0xF0 + ((wc >> 18) & 0x07);
> + ps->__value.__wchb[2] = 0x80 + ((wc >> 12) & 0x3F);
> + ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
> + ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
> + ps->__value.__wchb[3] = 2;
> + ps->__count |= 0x80000000;
> + }
> + }
> + if (result == 0 && wc != 0)
> + {
> + /* mbrtowc() never returns -3. When a MB sequence converts to multiple
> + WCs, no input is consumed when writing the subsequent WCs resulting
> + in a result of 0 even if a null character wasn't written. */
> + result = -3;
> + }
> +
> + return result;
> +}
> diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
> index 051cdcbeb5..c37e8619a0 100644
> --- a/wcsmbs/uchar.h
> +++ b/wcsmbs/uchar.h
> @@ -31,6 +31,13 @@
> #include <bits/types.h>
> #include <bits/types/mbstate_t.h>
>
> +/* Declare the C2x char8_t typedef in C2x modes, but only if the C++
> + __cpp_char8_t feature test macro is not defined. */
> +#if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
> +/* Define the 8-bit character type. */
> +typedef unsigned char char8_t;
> +#endif
> +
> #ifndef __USE_ISOCXX11
> /* Define the 16-bit and 32-bit character types. */
> typedef __uint_least16_t char16_t;
> @@ -40,6 +47,20 @@ typedef __uint_least32_t char32_t;
>
> __BEGIN_DECLS
>
> +/* Declare the C2x mbrtoc8() and c8rtomb() functions in C2x modes or if
> + the C++ __cpp_char8_t feature test macro is defined. */
> +#if __GLIBC_USE (ISOC2X) || defined __cpp_char8_t
> +/* Write char8_t representation of multibyte character pointed
> + to by S to PC8. */
> +extern size_t mbrtoc8 (char8_t *__restrict __pc8,
> + const char *__restrict __s, size_t __n,
> + mbstate_t *__restrict __p) __THROW;
> +
> +/* Write multibyte representation of char8_t C8 to S. */
> +extern size_t c8rtomb (char *__restrict __s, char8_t __c8,
> + mbstate_t *__restrict __ps) __THROW;
> +#endif
> +
> /* Write char16_t representation of multibyte character pointed
> to by S to PC16. */
> extern size_t mbrtoc16 (char16_t *__restrict __pc16,
> --
> 2.32.0
>
This change appears to introduce a failure of
wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
produces:
../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
38 | typedef unsigned char char8_t;
(recall we want our installed headers to avoid warnings *without* relying
on the default disabling of warnings in system headers).
Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
__extension__ (unlike what the C front end does), so simply adding
__extension__ to that declaration wouldn't help, but we could use
diagnostic disabling pragmas (as already done in some installed headers).
On 19/07/22 18:08, Joseph Myers wrote:
> This change appears to introduce a failure of
> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
> produces:
>
> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
> 38 | typedef unsigned char char8_t;
>
> (recall we want our installed headers to avoid warnings *without* relying
> on the default disabling of warnings in system headers).
>
> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
> __extension__ (unlike what the C front end does), so simply adding
> __extension__ to that declaration wouldn't help, but we could use
> diagnostic disabling pragmas (as already done in some installed headers).
>
My understanding is compiler will define __cpp_char8_t exactly to avoid
such redefinition. But it seems from gcc documentation that it is only
actually enabled with -fchar8_t. Do we a preprocessor flag to indicate
it?
* Adhemerval Zanella Netto via Libc-alpha:
> On 19/07/22 18:08, Joseph Myers wrote:
>> This change appears to introduce a failure of
>> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
>> produces:
>>
>> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
>> 38 | typedef unsigned char char8_t;
>>
>> (recall we want our installed headers to avoid warnings *without* relying
>> on the default disabling of warnings in system headers).
>>
>> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
>> __extension__ (unlike what the C front end does), so simply adding
>> __extension__ to that declaration wouldn't help, but we could use
>> diagnostic disabling pragmas (as already done in some installed headers).
> My understanding is compiler will define __cpp_char8_t exactly to avoid
> such redefinition. But it seems from gcc documentation that it is only
> actually enabled with -fchar8_t. Do we a preprocessor flag to indicate
> it?
I think __cpp_char8_t is only defined if the language mode is active.
The warning is independent of the language mode, though.
Thanks,
Florian
On 20/07/22 10:54, Florian Weimer wrote:
> * Adhemerval Zanella Netto via Libc-alpha:
>
>> On 19/07/22 18:08, Joseph Myers wrote:
>>> This change appears to introduce a failure of
>>> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
>>> produces:
>>>
>>> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
>>> 38 | typedef unsigned char char8_t;
>>>
>>> (recall we want our installed headers to avoid warnings *without* relying
>>> on the default disabling of warnings in system headers).
>>>
>>> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
>>> __extension__ (unlike what the C front end does), so simply adding
>>> __extension__ to that declaration wouldn't help, but we could use
>>> diagnostic disabling pragmas (as already done in some installed headers).
>
>> My understanding is compiler will define __cpp_char8_t exactly to avoid
>> such redefinition. But it seems from gcc documentation that it is only
>> actually enabled with -fchar8_t. Do we a preprocessor flag to indicate
>> it?
>
> I think __cpp_char8_t is only defined if the language mode is active.
> The warning is independent of the language mode, though.
Maybe we also skip chat8_t definition for __cplusplus == 202002L ?
* Adhemerval Zanella Netto:
>> I think __cpp_char8_t is only defined if the language mode is active.
>> The warning is independent of the language mode, though.
>
> Maybe we also skip chat8_t definition for __cplusplus == 202002L ?
We have to do that in any case, but we still need to deal with the
warning in the earlier language modes.
Thanks,
Florian
Confirmed that this issue can be easily reproduced outside the testsuite.
$ cat t.cpp
#include <uchar.h>
$ g++ --version
g++ (GCC) 13.0.0 20220720 (experimental)
...
$ g++ -c -I/path/to/glibc-char8_t/include -std=c++17
-Werror=c++20-compat t.cpp
In file included from t.cpp:1:
/home/tom/products/glibc-char8_t/include/uchar.h:38:23: error:
identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
38 | typedef unsigned char char8_t;
| ^~~~~~~
cc1plus: some warnings being treated as errors
The char8_t typedef is currently guarded by:
/* Declare the C2x char8_t typedef in C2x modes, but only if the C++
__cpp_char8_t feature test macro is not defined. */
#if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
/* Define the 8-bit character type. */
typedef unsigned char char8_t;
#endif
__GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally
defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or
should only) imply __GLIBC_USE (ISOC11).
Regardless, it seems that directives should be added to suppress the
diagnostic. I tried prototyping such a fix, but it doesn't seem to work
for me. I don't understand why.
$ diff -U3 uchar.h.old uchar.h
--- uchar.h.old 2022-07-20 12:37:55.544301692 -0400
+++ uchar.h 2022-07-20 12:43:21.124365563 -0400
@@ -34,8 +34,17 @@
/* Declare the C2x char8_t typedef in C2x modes, but only if the C++
__cpp_char8_t feature test macro is not defined. */
#if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
+/* Suppress the C++20 compatability diagnostic regarding char8_t being a
+ keyword. */
+#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wc++20-compat"
+#endif
/* Define the 8-bit character type. */
typedef unsigned char char8_t;
+#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic pop
+#endif
#endif
#ifndef __USE_ISOCXX11
Tom.
On 7/19/22 5:08 PM, Joseph Myers wrote:
> This change appears to introduce a failure of
> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
> produces:
>
> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
> 38 | typedef unsigned char char8_t;
>
> (recall we want our installed headers to avoid warnings *without* relying
> on the default disabling of warnings in system headers).
>
> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
> __extension__ (unlike what the C front end does), so simply adding
> __extension__ to that declaration wouldn't help, but we could use
> diagnostic disabling pragmas (as already done in some installed headers).
>
On 7/20/22 11:05 AM, Florian Weimer wrote:
> * Adhemerval Zanella Netto:
>
>>> I think __cpp_char8_t is only defined if the language mode is active.
>>> The warning is independent of the language mode, though.
>> Maybe we also skip chat8_t definition for __cplusplus == 202002L ?
> We have to do that in any case, but we still need to deal with the
> warning in the earlier language modes.
Declaring the char8_t typedef (and related mbrtoc8 and c8rtomb
functions) in C++ modes that don't enable the builtin char8_t type
(including -std=c++20 -fno-char8_t) is beneficial for compatibility with
C in C23 or _GNU_SOURCE modes.
Tom.
>
> Thanks,
> Florian
>
On 20/07/22 13:47, Tom Honermann wrote:
> Confirmed that this issue can be easily reproduced outside the testsuite.
>
> $ cat t.cpp
> #include <uchar.h>
>
> $ g++ --version
> g++ (GCC) 13.0.0 20220720 (experimental)
> ...
>
> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
> In file included from t.cpp:1:
> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
> 38 | typedef unsigned char char8_t;
> | ^~~~~~~
> cc1plus: some warnings being treated as errors
>
> The char8_t typedef is currently guarded by:
>
> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
> __cpp_char8_t feature test macro is not defined. */
> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
> /* Define the 8-bit character type. */
> typedef unsigned char char8_t;
> #endif
>
> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>
> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
I have tried as well and I can't get to work either. It would expect to work
as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>
> $ diff -U3 uchar.h.old uchar.h
> --- uchar.h.old 2022-07-20 12:37:55.544301692 -0400
> +++ uchar.h 2022-07-20 12:43:21.124365563 -0400
> @@ -34,8 +34,17 @@
> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
> __cpp_char8_t feature test macro is not defined. */
> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
> +/* Suppress the C++20 compatability diagnostic regarding char8_t being a
> + keyword. */
> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
> +# pragma GCC diagnostic push
> +# pragma GCC diagnostic ignored "-Wc++20-compat"
> +#endif
> /* Define the 8-bit character type. */
> typedef unsigned char char8_t;
> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
> +# pragma GCC diagnostic pop
> +#endif
> #endif
>
> #ifndef __USE_ISOCXX11
>
> Tom.
>
> On 7/19/22 5:08 PM, Joseph Myers wrote:
>> This change appears to introduce a failure of
>> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
>> produces:
>>
>> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
>> 38 | typedef unsigned char char8_t;
>>
>> (recall we want our installed headers to avoid warnings *without* relying
>> on the default disabling of warnings in system headers).
>>
>> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
>> __extension__ (unlike what the C front end does), so simply adding
>> __extension__ to that declaration wouldn't help, but we could use
>> diagnostic disabling pragmas (as already done in some installed headers).
>>
On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>
> On 20/07/22 13:47, Tom Honermann wrote:
>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>
>> $ cat t.cpp
>> #include <uchar.h>
>>
>> $ g++ --version
>> g++ (GCC) 13.0.0 20220720 (experimental)
>> ...
>>
>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>> In file included from t.cpp:1:
>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>> 38 | typedef unsigned char char8_t;
>> | ^~~~~~~
>> cc1plus: some warnings being treated as errors
>>
>> The char8_t typedef is currently guarded by:
>>
>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>> __cpp_char8_t feature test macro is not defined. */
>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>> /* Define the 8-bit character type. */
>> typedef unsigned char char8_t;
>> #endif
>>
>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>
>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
> I have tried as well and I can't get to work either. It would expect to work
> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
Yes, this appears to be a gcc issue. I spent some time looking at gcc
source code, but didn't find anything obvious. I verified the same
technique does work to suppress the similar warning issued for use of,
e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I
found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat",
but none for -Wc++20-compat (or -Wc++11-compat).
Tom.
>
>> $ diff -U3 uchar.h.old uchar.h
>> --- uchar.h.old 2022-07-20 12:37:55.544301692 -0400
>> +++ uchar.h 2022-07-20 12:43:21.124365563 -0400
>> @@ -34,8 +34,17 @@
>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>> __cpp_char8_t feature test macro is not defined. */
>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>> +/* Suppress the C++20 compatability diagnostic regarding char8_t being a
>> + keyword. */
>> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
>> +# pragma GCC diagnostic push
>> +# pragma GCC diagnostic ignored "-Wc++20-compat"
>> +#endif
>> /* Define the 8-bit character type. */
>> typedef unsigned char char8_t;
>> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
>> +# pragma GCC diagnostic pop
>> +#endif
>> #endif
>>
>> #ifndef __USE_ISOCXX11
>>
>> Tom.
>>
>> On 7/19/22 5:08 PM, Joseph Myers wrote:
>>> This change appears to introduce a failure of
>>> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
>>> produces:
>>>
>>> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
>>> 38 | typedef unsigned char char8_t;
>>>
>>> (recall we want our installed headers to avoid warnings *without* relying
>>> on the default disabling of warnings in system headers).
>>>
>>> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
>>> __extension__ (unlike what the C front end does), so simply adding
>>> __extension__ to that declaration wouldn't help, but we could use
>>> diagnostic disabling pragmas (as already done in some installed headers).
>>>
On 21/07/22 17:51, Tom Honermann wrote:
> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>
>> On 20/07/22 13:47, Tom Honermann wrote:
>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>
>>> $ cat t.cpp
>>> #include <uchar.h>
>>>
>>> $ g++ --version
>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>> ...
>>>
>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>> In file included from t.cpp:1:
>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>> 38 | typedef unsigned char char8_t;
>>> | ^~~~~~~
>>> cc1plus: some warnings being treated as errors
>>>
>>> The char8_t typedef is currently guarded by:
>>>
>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>> __cpp_char8_t feature test macro is not defined. */
>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>> /* Define the 8-bit character type. */
>>> typedef unsigned char char8_t;
>>> #endif
>>>
>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>
>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>> I have tried as well and I can't get to work either. It would expect to work
>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>
> Yes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>
> Tom.
>
In any case I think the fix below is the correct way (in fact I don't see
another way so I am assuming a compiler issue here). We also need to avoid
declare the typedef for __cplusplus >= 202002L.
>>
>>> $ diff -U3 uchar.h.old uchar.h
>>> --- uchar.h.old 2022-07-20 12:37:55.544301692 -0400
>>> +++ uchar.h 2022-07-20 12:43:21.124365563 -0400
>>> @@ -34,8 +34,17 @@
>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>> __cpp_char8_t feature test macro is not defined. */
>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>> +/* Suppress the C++20 compatability diagnostic regarding char8_t being a
>>> + keyword. */
>>> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
Use __GNUC_PREREQ.
>>> +# pragma GCC diagnostic push
>>> +# pragma GCC diagnostic ignored "-Wc++20-compat"
>>> +#endif
>>> /* Define the 8-bit character type. */
>>> typedef unsigned char char8_t;
>>> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
>>> +# pragma GCC diagnostic pop
>>> +#endif
>>> #endif
>>>
>>> #ifndef __USE_ISOCXX11
>>>
>>> Tom.
>>>
>>> On 7/19/22 5:08 PM, Joseph Myers wrote:
>>>> This change appears to introduce a failure of
>>>> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
>>>> produces:
>>>>
>>>> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
>>>> 38 | typedef unsigned char char8_t;
>>>>
>>>> (recall we want our installed headers to avoid warnings *without* relying
>>>> on the default disabling of warnings in system headers).
>>>>
>>>> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
>>>> __extension__ (unlike what the C front end does), so simply adding
>>>> __extension__ to that declaration wouldn't help, but we could use
>>>> diagnostic disabling pragmas (as already done in some installed headers).
>>>>
On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>
> On 21/07/22 17:51, Tom Honermann wrote:
>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>>
>>>> $ cat t.cpp
>>>> #include <uchar.h>
>>>>
>>>> $ g++ --version
>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>> ...
>>>>
>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>>> In file included from t.cpp:1:
>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>> 38 | typedef unsigned char char8_t;
>>>> | ^~~~~~~
>>>> cc1plus: some warnings being treated as errors
>>>>
>>>> The char8_t typedef is currently guarded by:
>>>>
>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>> __cpp_char8_t feature test macro is not defined. */
>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>> /* Define the 8-bit character type. */
>>>> typedef unsigned char char8_t;
>>>> #endif
>>>>
>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>>
>>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>>> I have tried as well and I can't get to work either. It would expect to work
>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>> Yes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>
>> Tom.
>>
> In any case I think the fix below is the correct way (in fact I don't see
> another way so I am assuming a compiler issue here).
I agree. I debugged gcc tonight and discovered what the problem was.
I'll submit a patch to gcc.
> We also need to avoid
> declare the typedef for __cplusplus >= 202002L.
The typedef is already avoided if the __cpp_char8_t feature test macro
is defined (builtin char8_t support can be enabled in previous C++
standard modes via the -fchar8_t option).
>
>>>> $ diff -U3 uchar.h.old uchar.h
>>>> --- uchar.h.old 2022-07-20 12:37:55.544301692 -0400
>>>> +++ uchar.h 2022-07-20 12:43:21.124365563 -0400
>>>> @@ -34,8 +34,17 @@
>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>> __cpp_char8_t feature test macro is not defined. */
>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>> +/* Suppress the C++20 compatability diagnostic regarding char8_t being a
>>>> + keyword. */
>>>> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
> Use __GNUC_PREREQ.
Yes, thank you. I also determined that the -Wc++20-compat option was
added to gcc 10 and is only recognized in C++ modes, so the diagnostic
suppression guards will be __GNUC_PREREQ (10, 0) && defined __cplusplus.
I'll follow up with a patch soon.
Tom.
>
>>>> +# pragma GCC diagnostic push
>>>> +# pragma GCC diagnostic ignored "-Wc++20-compat"
>>>> +#endif
>>>> /* Define the 8-bit character type. */
>>>> typedef unsigned char char8_t;
>>>> +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
>>>> +# pragma GCC diagnostic pop
>>>> +#endif
>>>> #endif
>>>>
>>>> #ifndef __USE_ISOCXX11
>>>>
>>>> Tom.
>>>>
>>>> On 7/19/22 5:08 PM, Joseph Myers wrote:
>>>>> This change appears to introduce a failure of
>>>>> wcsmbs/check-installed-headers-cxx with GCC mainline, because uchar.h now
>>>>> produces:
>>>>>
>>>>> ../wcsmbs/uchar.h:38:23: error: identifier 'char8_t' is a keyword in C++20 [-Werror=c++20-compat]
>>>>> 38 | typedef unsigned char char8_t;
>>>>>
>>>>> (recall we want our installed headers to avoid warnings *without* relying
>>>>> on the default disabling of warnings in system headers).
>>>>>
>>>>> Unfortunately, GCC for C++ doesn't disable -Wc++20-compat inside
>>>>> __extension__ (unlike what the C front end does), so simply adding
>>>>> __extension__ to that declaration wouldn't help, but we could use
>>>>> diagnostic disabling pragmas (as already done in some installed headers).
>>>>>
On 22/07/22 02:24, Tom Honermann wrote:
> On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>>
>> On 21/07/22 17:51, Tom Honermann wrote:
>>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>>>
>>>>> $ cat t.cpp
>>>>> #include <uchar.h>
>>>>>
>>>>> $ g++ --version
>>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>>> ...
>>>>>
>>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>>>> In file included from t.cpp:1:
>>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>>> 38 | typedef unsigned char char8_t;
>>>>> | ^~~~~~~
>>>>> cc1plus: some warnings being treated as errors
>>>>>
>>>>> The char8_t typedef is currently guarded by:
>>>>>
>>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>>> __cpp_char8_t feature test macro is not defined. */
>>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>>> /* Define the 8-bit character type. */
>>>>> typedef unsigned char char8_t;
>>>>> #endif
>>>>>
>>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>>>
>>>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>>>> I have tried as well and I can't get to work either. It would expect to work
>>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>>> Yes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>>
>>> Tom.
>>>
>> In any case I think the fix below is the correct way (in fact I don't see
>> another way so I am assuming a compiler issue here).
> I agree. I debugged gcc tonight and discovered what the problem was. I'll submit a patch to gcc.
>> We also need to avoid
>> declare the typedef for __cplusplus >= 202002L.
> The typedef is already avoided if the __cpp_char8_t feature test macro is defined (builtin char8_t support can be enabled in previous C++ standard modes via the -fchar8_t option).
If the compiler preprocessor defined for -std=c++20? I had the impression it is
enabled iff -fchar8_t is set.
On 22/07/22 08:21, Adhemerval Zanella Netto wrote:
>
>
> On 22/07/22 02:24, Tom Honermann wrote:
>> On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>>>
>>> On 21/07/22 17:51, Tom Honermann wrote:
>>>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>>>>
>>>>>> $ cat t.cpp
>>>>>> #include <uchar.h>
>>>>>>
>>>>>> $ g++ --version
>>>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>>>> ...
>>>>>>
>>>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>>>>> In file included from t.cpp:1:
>>>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>>>> 38 | typedef unsigned char char8_t;
>>>>>> | ^~~~~~~
>>>>>> cc1plus: some warnings being treated as errors
>>>>>>
>>>>>> The char8_t typedef is currently guarded by:
>>>>>>
>>>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>>>> __cpp_char8_t feature test macro is not defined. */
>>>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>>>> /* Define the 8-bit character type. */
>>>>>> typedef unsigned char char8_t;
>>>>>> #endif
>>>>>>
>>>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>>>>
>>>>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>>>>> I have tried as well and I can't get to work either. It would expect to work
>>>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>>>> Yes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>>>
>>>> Tom.
>>>>
>>> In any case I think the fix below is the correct way (in fact I don't see
>>> another way so I am assuming a compiler issue here).
>> I agree. I debugged gcc tonight and discovered what the problem was. I'll submit a patch to gcc.
>>> We also need to avoid
>>> declare the typedef for __cplusplus >= 202002L.
>> The typedef is already avoided if the __cpp_char8_t feature test macro is defined (builtin char8_t support can be enabled in previous C++ standard modes via the -fchar8_t option).
>
> If the compiler preprocessor defined for -std=c++20? I had the impression it is
> enabled iff -fchar8_t is set.
I realized now I did not write proper english, I meant to ask if gcc always define
__cpp_char8_t for -std=c++20 and higher since I had the impression that the
define is only active iff -fchar8_t is actively used.
On 7/22/22 10:15 AM, Adhemerval Zanella Netto wrote:
>
> On 22/07/22 08:21, Adhemerval Zanella Netto wrote:
>>
>> On 22/07/22 02:24, Tom Honermann wrote:
>>> On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>>>> On 21/07/22 17:51, Tom Honermann wrote:
>>>>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>>>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>>>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>>>>>
>>>>>>> $ cat t.cpp
>>>>>>> #include <uchar.h>
>>>>>>>
>>>>>>> $ g++ --version
>>>>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>>>>> ...
>>>>>>>
>>>>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>>>>>> In file included from t.cpp:1:
>>>>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>>>>> 38 | typedef unsigned char char8_t;
>>>>>>> | ^~~~~~~
>>>>>>> cc1plus: some warnings being treated as errors
>>>>>>>
>>>>>>> The char8_t typedef is currently guarded by:
>>>>>>>
>>>>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>>>>> __cpp_char8_t feature test macro is not defined. */
>>>>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>>>>> /* Define the 8-bit character type. */
>>>>>>> typedef unsigned char char8_t;
>>>>>>> #endif
>>>>>>>
>>>>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>>>>>
>>>>>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>>>>>> I have tried as well and I can't get to work either. It would expect to work
>>>>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>>>>> prereqYes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>>>>
>>>>> Tom.
>>>>>
>>>> In any case I think the fix below is the correct way (in fact I don't see
>>>> another way so I am assuming a compiler issue here).
>>> I agree. I debugged gcc tonight and discovered what the problem was. I'll submit a patch to gcc.
>>>> We also need to avoid
>>>> declare the typedef for __cplusplus >= 202002L.
>>> The typedef is already avoided if the __cpp_char8_t feature test macro is defined (builtin char8_t support can be enabled in previous C++ standard modes via the -fchar8_t option).
>> If the compiler preprocessor defined for -std=c++20? I had the impression it is
>> enabled iff -fchar8_t is set.
> I realized now I did not write proper english, I meant to ask if gcc always define
> __cpp_char8_t for -std=c++20 and higher since I had the impression that the
> define is only active iff -fchar8_t is actively used.
English is hard :)
For gcc, clang, and MSVC, -std=c++20 (/std:c++20 for MSVC) implies
-fchar8_t (/Zc:char8_t), but that feature can be disabled with
-fno-char8_t (/Zc:char8_t-). For example:
$ gcc -E -dM -x c++ -std=c++17 /dev/null | grep __cpp_char8_t
$ gcc -E -dM -x c++ -std=c++17 -fchar8_t /dev/null | grep __cpp_char8_t
#define __cpp_char8_t 201811L
$ gcc -E -dM -x c++ -std=c++20 /dev/null | grep __cpp_char8_t
#define __cpp_char8_t 201811L
$ gcc -E -dM -x c++ -std=c++20 -fno-char8_t /dev/null | grep __cpp_char8_t
Tom.
On 22/07/22 14:00, Tom Honermann wrote:
> On 7/22/22 10:15 AM, Adhemerval Zanella Netto wrote:
>>
>> On 22/07/22 08:21, Adhemerval Zanella Netto wrote:
>>>
>>> On 22/07/22 02:24, Tom Honermann wrote:
>>>> On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>>>>> On 21/07/22 17:51, Tom Honermann wrote:
>>>>>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>>>>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>>>>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>>>>>>
>>>>>>>> $ cat t.cpp
>>>>>>>> #include <uchar.h>
>>>>>>>>
>>>>>>>> $ g++ --version
>>>>>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>>>>>> ...
>>>>>>>>
>>>>>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>>>>>>> In file included from t.cpp:1:
>>>>>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>>>>>> 38 | typedef unsigned char char8_t;
>>>>>>>> | ^~~~~~~
>>>>>>>> cc1plus: some warnings being treated as errors
>>>>>>>>
>>>>>>>> The char8_t typedef is currently guarded by:
>>>>>>>>
>>>>>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>>>>>> __cpp_char8_t feature test macro is not defined. */
>>>>>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>>>>>> /* Define the 8-bit character type. */
>>>>>>>> typedef unsigned char char8_t;
>>>>>>>> #endif
>>>>>>>>
>>>>>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>>>>>>
>>>>>>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>>>>>>> I have tried as well and I can't get to work either. It would expect to work
>>>>>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>>>>>> prereqYes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>>>>>
>>>>>> Tom.
>>>>>>
>>>>> In any case I think the fix below is the correct way (in fact I don't see
>>>>> another way so I am assuming a compiler issue here).
>>>> I agree. I debugged gcc tonight and discovered what the problem was. I'll submit a patch to gcc.
>>>>> We also need to avoid
>>>>> declare the typedef for __cplusplus >= 202002L.
>>>> The typedef is already avoided if the __cpp_char8_t feature test macro is defined (builtin char8_t support can be enabled in previous C++ standard modes via the -fchar8_t option).
>>> If the compiler preprocessor defined for -std=c++20? I had the impression it is
>>> enabled iff -fchar8_t is set.
>> I realized now I did not write proper english, I meant to ask if gcc always define
>> __cpp_char8_t for -std=c++20 and higher since I had the impression that the
>> define is only active iff -fchar8_t is actively used.
>
> English is hard :)
>
> For gcc, clang, and MSVC, -std=c++20 (/std:c++20 for MSVC) implies -fchar8_t (/Zc:char8_t), but that feature can be disabled with -fno-char8_t (/Zc:char8_t-). For example:
>
> $ gcc -E -dM -x c++ -std=c++17 /dev/null | grep __cpp_char8_t
> $ gcc -E -dM -x c++ -std=c++17 -fchar8_t /dev/null | grep __cpp_char8_t
> #define __cpp_char8_t 201811L
> $ gcc -E -dM -x c++ -std=c++20 /dev/null | grep __cpp_char8_t
> #define __cpp_char8_t 201811L
> $ gcc -E -dM -x c++ -std=c++20 -fno-char8_t /dev/null | grep __cpp_char8_t
>
> Tom.
>
Ok, thanks.
On 7/22/22 1:24 AM, Tom Honermann via Libc-alpha wrote:
> On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>>
>> On 21/07/22 17:51, Tom Honermann wrote:
>>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>>> Confirmed that this issue can be easily reproduced outside the
>>>>> testsuite.
>>>>>
>>>>> $ cat t.cpp
>>>>> #include <uchar.h>
>>>>>
>>>>> $ g++ --version
>>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>>> ...
>>>>>
>>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17
>>>>> -Werror=c++20-compat t.cpp
>>>>> In file included from t.cpp:1:
>>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error:
>>>>> identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>>> 38 | typedef unsigned char char8_t;
>>>>> | ^~~~~~~
>>>>> cc1plus: some warnings being treated as errors
>>>>>
>>>>> The char8_t typedef is currently guarded by:
>>>>>
>>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>>> __cpp_char8_t feature test macro is not defined. */
>>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>>> /* Define the 8-bit character type. */
>>>>> typedef unsigned char char8_t;
>>>>> #endif
>>>>>
>>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally
>>>>> defines _GNU_SOURCE. I believe otherwise, C++17 mode would only
>>>>> (or should only) imply __GLIBC_USE (ISOC11).
>>>>>
>>>>> Regardless, it seems that directives should be added to suppress
>>>>> the diagnostic. I tried prototyping such a fix, but it doesn't
>>>>> seem to work for me. I don't understand why.
>>>> I have tried as well and I can't get to work either. It would
>>>> expect to work
>>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>>> Yes, this appears to be a gcc issue. I spent some time looking at
>>> gcc source code, but didn't find anything obvious. I verified the
>>> same technique does work to suppress the similar warning issued for
>>> use of, e.g., constexpr, as an identifier when -Wc++11-compat is
>>> enabled. I found tests that exercise #pragma GCC diagnostic ignored
>>> "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>>
>>> Tom.
>>>
>> In any case I think the fix below is the correct way (in fact I don't
>> see
>> another way so I am assuming a compiler issue here).
> I agree. I debugged gcc tonight and discovered what the problem was.
> I'll submit a patch to gcc.
A patch has been submitted to gcc to correct '#pragma GCC diagnostic
ignored' based suppression for -Wc++20-compat diagnostics. See the
thread at https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598736.html.
Tom.
@@ -46,6 +46,15 @@ Major new features:
to more flexibly configure and operate on filesystem mounts. The new
mount APIs are specifically designed to work with namespaces.
+* Support for the mbrtoc8 and c8rtomb multibyte/UTF-8 character conversion
+ functions has been added per the ISO C2X N2653 and C++20 P0482R6 proposals.
+ Support for the char8_t typedef has been added per the ISO C2X N2653
+ proposal. The functions are declared in uchar.h in C2X mode or when the
+ _GNU_SOURCE macro or C++20 __cpp_char8_t feature test macro is defined.
+ The char8_t typedef is declared in uchar.h in C2X mode or when the
+ _GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature test macro
+ is not defined (if __cpp_char8_t is defined, then char8_t is a builtin type).
+
Deprecated and removed features, and other changes affecting compatibility:
* Support for prelink will be removed in the next release; this includes
@@ -2289,6 +2289,8 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 close_range F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2616,8 +2616,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2713,8 +2713,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2377,8 +2377,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -496,8 +496,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -493,8 +493,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2652,8 +2652,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2601,8 +2601,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2785,8 +2785,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2551,8 +2551,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -497,8 +497,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2728,8 +2728,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2701,8 +2701,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2698,8 +2698,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2693,8 +2693,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2691,8 +2691,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2699,8 +2699,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2602,8 +2602,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2740,8 +2740,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2123,8 +2123,10 @@ GLIBC_2.35 wprintf F
GLIBC_2.35 write F
GLIBC_2.35 writev F
GLIBC_2.35 wscanf F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2755,8 +2755,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2788,8 +2788,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2510,8 +2510,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2812,8 +2812,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2379,8 +2379,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2579,8 +2579,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2753,8 +2753,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2547,8 +2547,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2608,8 +2608,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2605,8 +2605,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2748,8 +2748,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2574,8 +2574,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2525,8 +2525,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -2631,8 +2631,10 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
GLIBC_2.36 fsmount F
GLIBC_2.36 fsopen F
+GLIBC_2.36 mbrtoc8 F
GLIBC_2.36 move_mount F
GLIBC_2.36 pidfd_getfd F
GLIBC_2.36 pidfd_open F
@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
wcsmbsload mbsrtowcs_l \
isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
isoc99_swscanf isoc99_vswscanf \
- mbrtoc16 c16rtomb mbrtoc32 c32rtomb
+ mbrtoc8 c8rtomb mbrtoc16 c16rtomb mbrtoc32 c32rtomb
strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
@@ -49,4 +49,7 @@ libc {
wcstof32; wcstof64; wcstof32x;
wcstof32_l; wcstof64_l; wcstof32x_l;
}
+ GLIBC_2.36 {
+ c8rtomb; mbrtoc8;
+ }
}
new file mode 100644
@@ -0,0 +1,132 @@
+/* UTF-8 to multibyte conversion.
+ Copyright (C) 2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <uchar.h>
+#include <wchar.h>
+
+
+/* This is the private state used if PS is NULL. */
+static mbstate_t state;
+
+size_t
+c8rtomb (char *s, char8_t c8, mbstate_t *ps)
+{
+ /* This implementation depends on the converter invoked by wcrtomb not
+ needing to retain state in either the top most bit of ps->__count or
+ in ps->__value between invocations. This implementation uses the
+ top most bit of ps->__count to indicate that trailing code units are
+ expected and uses ps->__value to store previously seen code units. */
+
+ wchar_t wc;
+
+ if (ps == NULL)
+ ps = &state;
+
+ if (s == NULL)
+ {
+ /* if 's' is a null pointer, behave as if u8'\0' was passed as 'c8'. If
+ this occurs for an incomplete code unit sequence, then an error will
+ be reported below. */
+ c8 = u8""[0];
+ }
+
+ if (! (ps->__count & 0x80000000))
+ {
+ /* Initial state. */
+ if ((c8 >= 0x80 && c8 <= 0xC1) || c8 >= 0xF5)
+ {
+ /* An invalid lead code unit. */
+ __set_errno (EILSEQ);
+ return -1;
+ }
+ if (c8 >= 0xC2)
+ {
+ /* A valid lead code unit. */
+ ps->__count |= 0x80000000;
+ ps->__value.__wchb[0] = c8;
+ ps->__value.__wchb[3] = 1;
+ return 0;
+ }
+ /* A single byte (ASCII) code unit. */
+ wc = c8;
+ }
+ else
+ {
+ char8_t cu1 = ps->__value.__wchb[0];
+ if (ps->__value.__wchb[3] == 1)
+ {
+ /* A single lead code unit was previously seen. */
+ if ((c8 < 0x80 || c8 > 0xBF)
+ || (cu1 == 0xE0 && c8 < 0xA0)
+ || (cu1 == 0xED && c8 > 0x9F)
+ || (cu1 == 0xF0 && c8 < 0x90)
+ || (cu1 == 0xF4 && c8 > 0x8F))
+ {
+ /* An invalid second code unit. */
+ __set_errno (EILSEQ);
+ return -1;
+ }
+ if (cu1 >= 0xE0)
+ {
+ /* A three or four code unit sequence. */
+ ps->__value.__wchb[1] = c8;
+ ++ps->__value.__wchb[3];
+ return 0;
+ }
+ wc = ((cu1 & 0x1F) << 6)
+ + (c8 & 0x3F);
+ }
+ else
+ {
+ char8_t cu2 = ps->__value.__wchb[1];
+ /* A three or four byte code unit sequence. */
+ if (c8 < 0x80 || c8 > 0xBF)
+ {
+ /* An invalid third or fourth code unit. */
+ __set_errno (EILSEQ);
+ return -1;
+ }
+ if (ps->__value.__wchb[3] == 2 && cu1 >= 0xF0)
+ {
+ /* A four code unit sequence. */
+ ps->__value.__wchb[2] = c8;
+ ++ps->__value.__wchb[3];
+ return 0;
+ }
+ if (cu1 < 0xF0)
+ {
+ wc = ((cu1 & 0x0F) << 12)
+ + ((cu2 & 0x3F) << 6)
+ + (c8 & 0x3F);
+ }
+ else
+ {
+ char8_t cu3 = ps->__value.__wchb[2];
+ wc = ((cu1 & 0x07) << 18)
+ + ((cu2 & 0x3F) << 12)
+ + ((cu3 & 0x3F) << 6)
+ + (c8 & 0x3F);
+ }
+ }
+ ps->__count &= 0x7fffffff;
+ ps->__value.__wch = 0;
+ }
+
+ return wcrtomb (s, wc, ps);
+}
new file mode 100644
@@ -0,0 +1,126 @@
+/* Multibyte to UTF-8 conversion.
+ Copyright (C) 2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gconv.h>
+#include <uchar.h>
+#include <wcsmbsload.h>
+
+#include <sysdep.h>
+
+#ifndef EILSEQ
+# define EILSEQ EINVAL
+#endif
+
+
+/* This is the private state used if PS is NULL. */
+static mbstate_t state;
+
+size_t
+mbrtoc8 (char8_t *pc8, const char *s, size_t n, mbstate_t *ps)
+{
+ /* This implementation depends on the converter invoked by mbrtowc() not
+ needing to retain state in either the top most bit of ps->__count or
+ in ps->__value between invocations. This implementation uses the
+ top most bit of ps->__count to indicate that trailing code units are
+ yet to be written and uses ps->__value to store those code units. */
+
+ if (ps == NULL)
+ ps = &state;
+
+ /* If state indicates that trailing code units are yet to be written, write
+ those first regardless of whether 's' is a null pointer. */
+ if (ps->__count & 0x80000000)
+ {
+ /* ps->__value.__wchb[3] stores the index of the next code unit to
+ write. Code units are stored in reverse order. */
+ size_t i = ps->__value.__wchb[3];
+ if (pc8 != NULL)
+ {
+ *pc8 = ps->__value.__wchb[i];
+ }
+ if (i == 0)
+ {
+ ps->__count &= 0x7fffffff;
+ ps->__value.__wch = 0;
+ }
+ else
+ --ps->__value.__wchb[3];
+ return -3;
+ }
+
+ if (s == NULL)
+ {
+ /* if 's' is a null pointer, behave as if a null pointer was passed for
+ 'pc8', an empty string was passed for 's', and 1 passed for 'n'. */
+ pc8 = NULL;
+ s = "";
+ n = 1;
+ }
+
+ wchar_t wc;
+ size_t result;
+
+ result = mbrtowc (&wc, s, n, ps);
+ if (result <= n)
+ {
+ if (wc <= 0x7F)
+ {
+ if (pc8 != NULL)
+ *pc8 = wc;
+ }
+ else if (wc <= 0x7FF)
+ {
+ if (pc8 != NULL)
+ *pc8 = 0xC0 + ((wc >> 6) & 0x1F);
+ ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+ ps->__value.__wchb[3] = 0;
+ ps->__count |= 0x80000000;
+ }
+ else if (wc <= 0xFFFF)
+ {
+ if (pc8 != NULL)
+ *pc8 = 0xE0 + ((wc >> 12) & 0x0F);
+ ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+ ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+ ps->__value.__wchb[3] = 1;
+ ps->__count |= 0x80000000;
+ }
+ else if (wc <= 0x10FFFF)
+ {
+ if (pc8 != NULL)
+ *pc8 = 0xF0 + ((wc >> 18) & 0x07);
+ ps->__value.__wchb[2] = 0x80 + ((wc >> 12) & 0x3F);
+ ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+ ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+ ps->__value.__wchb[3] = 2;
+ ps->__count |= 0x80000000;
+ }
+ }
+ if (result == 0 && wc != 0)
+ {
+ /* mbrtowc() never returns -3. When a MB sequence converts to multiple
+ WCs, no input is consumed when writing the subsequent WCs resulting
+ in a result of 0 even if a null character wasn't written. */
+ result = -3;
+ }
+
+ return result;
+}
@@ -31,6 +31,13 @@
#include <bits/types.h>
#include <bits/types/mbstate_t.h>
+/* Declare the C2x char8_t typedef in C2x modes, but only if the C++
+ __cpp_char8_t feature test macro is not defined. */
+#if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
+/* Define the 8-bit character type. */
+typedef unsigned char char8_t;
+#endif
+
#ifndef __USE_ISOCXX11
/* Define the 16-bit and 32-bit character types. */
typedef __uint_least16_t char16_t;
@@ -40,6 +47,20 @@ typedef __uint_least32_t char32_t;
__BEGIN_DECLS
+/* Declare the C2x mbrtoc8() and c8rtomb() functions in C2x modes or if
+ the C++ __cpp_char8_t feature test macro is defined. */
+#if __GLIBC_USE (ISOC2X) || defined __cpp_char8_t
+/* Write char8_t representation of multibyte character pointed
+ to by S to PC8. */
+extern size_t mbrtoc8 (char8_t *__restrict __pc8,
+ const char *__restrict __s, size_t __n,
+ mbstate_t *__restrict __p) __THROW;
+
+/* Write multibyte representation of char8_t C8 to S. */
+extern size_t c8rtomb (char *__restrict __s, char8_t __c8,
+ mbstate_t *__restrict __ps) __THROW;
+#endif
+
/* Write char16_t representation of multibyte character pointed
to by S to PC16. */
extern size_t mbrtoc16 (char16_t *__restrict __pc16,