[libcxx-commits] [libcxx] [libcxx] Define _LIBCPP_HAS_C8RTOMB_MBRTOC8 for picolibc (PR #152724)

Victor Campos via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 17 02:01:29 PDT 2025


https://github.com/vhscampos updated https://github.com/llvm/llvm-project/pull/152724

>From cd932a1733dc82b90613f4e4ee1ecc864a70e153 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Thu, 7 Aug 2025 16:03:44 +0100
Subject: [PATCH 1/9] [libcxx] Define _LIBCPP_HAS_C8RTOMB_MBRTOC8 for picolibc

Starting from picolibc 1.8.9, the `char8_t` related functions are
provided.

This patch adds logic to detect the underlying picolibc version and
define the `_LIBCPP_HAS_C8RTOMB_MBRTOC8 macro` accordingly.
---
 libcxx/include/__config                   | 8 ++++++--
 libcxx/include/__configuration/platform.h | 4 ++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 77a71b6cf1cae..ab87ed4787b84 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1027,8 +1027,12 @@ typedef __char32_t char32_t;
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
-#  else
-#    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
+#  elif defined (_LIBCPP_PICOLIBC_PREREQ)
+#    if _LIBCPP_PICOLIBC_PREREQ(1, 8, 9) && defined(__cpp_char8_t)
+#      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
+#    else
+#      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
+#    endif
 #  endif
 
 // There are a handful of public standard library types that are intended to
diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h
index f3c199dee172b..4f581a352038f 100644
--- a/libcxx/include/__configuration/platform.h
+++ b/libcxx/include/__configuration/platform.h
@@ -47,6 +47,10 @@
 //       user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism.
 #if __has_include(<picolibc.h>)
 #  include <picolibc.h>
+#  define _LIBCPP_PICOLIBC_VERSION_INT(maj, min, patch) (maj * 10000 + min * 100 + patch)
+#  define _LIBCPP_PICOLIBC_PREREQ(maj, min, patch)                                                                     \
+    _LIBCPP_PICOLIBC_VERSION_INT(__PICOLIBC__, __PICOLIBC_MINOR__, __PICOLIBC_PATCHLEVEL__) >=                         \
+        _LIBCPP_PICOLIBC_VERSION_INT(maj, min, patch)
 #endif
 
 #ifndef __BYTE_ORDER__

>From b60649719eae9693b3cdffa07b44460ee4d4eddf Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Fri, 8 Aug 2025 14:50:07 +0100
Subject: [PATCH 2/9] Fix clang-format issue

---
 libcxx/include/__config | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index ab87ed4787b84..3dc4d3ce0ed58 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1027,7 +1027,7 @@ typedef __char32_t char32_t;
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
-#  elif defined (_LIBCPP_PICOLIBC_PREREQ)
+#  elif defined(_LIBCPP_PICOLIBC_PREREQ)
 #    if _LIBCPP_PICOLIBC_PREREQ(1, 8, 9) && defined(__cpp_char8_t)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
 #    else

>From 8d87631ab35304dba67322106570bbbc330b6d13 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Mon, 11 Aug 2025 10:01:18 +0100
Subject: [PATCH 3/9] Refactor the preprocessor logic

---
 libcxx/include/__config | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 3dc4d3ce0ed58..e21d108ccf328 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1021,18 +1021,22 @@ typedef __char32_t char32_t;
 // the latter depends on internal GNU libc details that are not appropriate
 // to depend on here, so any declarations present when __cpp_char8_t is not
 // defined are ignored.
+//
+// picolibc 1.8.9 and newer declare the two functions unconditionally.
 #  if defined(_LIBCPP_GLIBC_PREREQ)
-#    if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
+#    if defined(__cpp_char8_t) && _LIBCPP_GLIBC_PREREQ(2, 36)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
 #  elif defined(_LIBCPP_PICOLIBC_PREREQ)
-#    if _LIBCPP_PICOLIBC_PREREQ(1, 8, 9) && defined(__cpp_char8_t)
+#    if _LIBCPP_PICOLIBC_PREREQ(1, 8, 9)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
+#  else
+#    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
 #  endif
 
 // There are a handful of public standard library types that are intended to

>From 91ea91e57af0ed2272d369b37e4b7675ba7713c6 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Tue, 12 Aug 2025 11:43:24 +0100
Subject: [PATCH 4/9] Handle Apple and MSVC explictly

---
 libcxx/include/__config | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index e21d108ccf328..53834eec7bc8c 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1023,6 +1023,8 @@ typedef __char32_t char32_t;
 // defined are ignored.
 //
 // picolibc 1.8.9 and newer declare the two functions unconditionally.
+//
+// Microsoft C Runtime and Apple C library do not yet support these functions.
 #  if defined(_LIBCPP_GLIBC_PREREQ)
 #    if defined(__cpp_char8_t) && _LIBCPP_GLIBC_PREREQ(2, 36)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
@@ -1035,6 +1037,8 @@ typedef __char32_t char32_t;
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
+#  elif defined(__APPLE__) || defined(_MSC_VER)
+#    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #  else
 #    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
 #  endif

>From def1139273a436f43daa2d6e88ffa74414c96a1d Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Tue, 12 Aug 2025 16:06:44 +0100
Subject: [PATCH 5/9] Handle AIX

---
 libcxx/include/__config | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 53834eec7bc8c..cc5cefa28d86f 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1024,7 +1024,8 @@ typedef __char32_t char32_t;
 //
 // picolibc 1.8.9 and newer declare the two functions unconditionally.
 //
-// Microsoft C Runtime and Apple C library do not yet support these functions.
+// Microsoft C Runtime, Apple C library and AIX C library do not yet support
+// these functions.
 #  if defined(_LIBCPP_GLIBC_PREREQ)
 #    if defined(__cpp_char8_t) && _LIBCPP_GLIBC_PREREQ(2, 36)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
@@ -1037,7 +1038,7 @@ typedef __char32_t char32_t;
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
-#  elif defined(__APPLE__) || defined(_MSC_VER)
+#  elif defined(__APPLE__) || defined(_MSC_VER) || defined(_AIX)
 #    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #  else
 #    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1

>From 5d7491a8b530bc0ae226784f5eeea7d0cf3a01a7 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Wed, 13 Aug 2025 12:12:55 +0100
Subject: [PATCH 6/9] Handle FreeBSD and Microsoft C Runtime library

---
 libcxx/include/__config | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index cc5cefa28d86f..2ce0c4448aae9 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1024,8 +1024,8 @@ typedef __char32_t char32_t;
 //
 // picolibc 1.8.9 and newer declare the two functions unconditionally.
 //
-// Microsoft C Runtime, Apple C library and AIX C library do not yet support
-// these functions.
+// Apple C library, Microsoft C Runtime, AIX C library and FreeBSD libc do not
+// yet support these functions.
 #  if defined(_LIBCPP_GLIBC_PREREQ)
 #    if defined(__cpp_char8_t) && _LIBCPP_GLIBC_PREREQ(2, 36)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
@@ -1038,7 +1038,7 @@ typedef __char32_t char32_t;
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
-#  elif defined(__APPLE__) || defined(_MSC_VER) || defined(_AIX)
+#  elif defined(__APPLE__) || defined(_MSC_VER) || defined(_LIBCPP_UCRT) || defined(_AIX) || defined(__FreeBSD__)
 #    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #  else
 #    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1

>From 27129d4fed1ad27aaeef95a90a37ddccaf9e6601 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Wed, 13 Aug 2025 12:17:03 +0100
Subject: [PATCH 7/9] Detect the UCRT library

---
 libcxx/include/__configuration/platform.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h
index 4f581a352038f..a448ca82b2935 100644
--- a/libcxx/include/__configuration/platform.h
+++ b/libcxx/include/__configuration/platform.h
@@ -53,6 +53,13 @@
         _LIBCPP_PICOLIBC_VERSION_INT(maj, min, patch)
 #endif
 
+#if __has_include(<corecrt.h>)
+#  include <corecrt.h>
+#  if defined(_UCRT)
+#    define _LIBCPP_UCRT
+#  endif
+#endif
+
 #ifndef __BYTE_ORDER__
 #  error                                                                                                               \
       "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform"

>From 205652ce005fb96a0e96bc7e89af623500e962fe Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Tue, 16 Sep 2025 14:18:59 +0100
Subject: [PATCH 8/9] List of changes:  - Define macro unconditionally when the
 compiler is clang.  - Remove preprocessor logic that isn't needed anymore.  -
 Define new libcxx test feature for the AIX platform.  - Mark tests as xfail
 in the platforms whose C library doesn't support    the char8_t functions.

---
 libcxx/include/__config                       | 19 ++++---------------
 libcxx/include/__configuration/platform.h     | 11 -----------
 .../depr.c.headers/uchar_h.compile.pass.cpp   |  5 +++++
 .../strings/c.strings/cuchar.compile.pass.cpp |  5 +++++
 .../c.strings/no_c8rtomb_mbrtoc8.verify.cpp   |  6 ++++++
 libcxx/utils/libcxx/test/features.py          |  1 +
 6 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 2ce0c4448aae9..06060cde8d0a1 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1021,27 +1021,16 @@ typedef __char32_t char32_t;
 // the latter depends on internal GNU libc details that are not appropriate
 // to depend on here, so any declarations present when __cpp_char8_t is not
 // defined are ignored.
-//
-// picolibc 1.8.9 and newer declare the two functions unconditionally.
-//
-// Apple C library, Microsoft C Runtime, AIX C library and FreeBSD libc do not
-// yet support these functions.
 #  if defined(_LIBCPP_GLIBC_PREREQ)
-#    if defined(__cpp_char8_t) && _LIBCPP_GLIBC_PREREQ(2, 36)
-#      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
-#    else
-#      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
-#    endif
-#  elif defined(_LIBCPP_PICOLIBC_PREREQ)
-#    if _LIBCPP_PICOLIBC_PREREQ(1, 8, 9)
+#    if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
 #    else
 #      define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #    endif
-#  elif defined(__APPLE__) || defined(_MSC_VER) || defined(_LIBCPP_UCRT) || defined(_AIX) || defined(__FreeBSD__)
-#    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
-#  else
+#  elif defined(__clang__)
 #    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
+#  else
+#    define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
 #  endif
 
 // There are a handful of public standard library types that are intended to
diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h
index a448ca82b2935..f3c199dee172b 100644
--- a/libcxx/include/__configuration/platform.h
+++ b/libcxx/include/__configuration/platform.h
@@ -47,17 +47,6 @@
 //       user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism.
 #if __has_include(<picolibc.h>)
 #  include <picolibc.h>
-#  define _LIBCPP_PICOLIBC_VERSION_INT(maj, min, patch) (maj * 10000 + min * 100 + patch)
-#  define _LIBCPP_PICOLIBC_PREREQ(maj, min, patch)                                                                     \
-    _LIBCPP_PICOLIBC_VERSION_INT(__PICOLIBC__, __PICOLIBC_MINOR__, __PICOLIBC_PATCHLEVEL__) >=                         \
-        _LIBCPP_PICOLIBC_VERSION_INT(maj, min, patch)
-#endif
-
-#if __has_include(<corecrt.h>)
-#  include <corecrt.h>
-#  if defined(_UCRT)
-#    define _LIBCPP_UCRT
-#  endif
 #endif
 
 #ifndef __BYTE_ORDER__
diff --git a/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp b/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
index a1560c8ee5853..11da50665dc9f 100644
--- a/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
+++ b/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
@@ -11,6 +11,11 @@
 // Apple platforms don't provide <uchar.h> yet, so these tests fail.
 // XFAIL: target={{.+}}-apple-{{.+}}
 
+// The following platforms do not provide mbrtoc8 and c8rtomb so the tests fail
+// XFAIL: aix
+// XFAIL: freebsd
+// XFAIL: windows
+
 // mbrtoc16 not defined.
 // XFAIL: LIBCXX-PICOLIBC-FIXME
 
diff --git a/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp b/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
index 2076384deb2b2..46c75e90c6780 100644
--- a/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
+++ b/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
@@ -11,6 +11,11 @@
 // Apple platforms don't provide <uchar.h> yet, so these tests fail.
 // XFAIL: target={{.+}}-apple-{{.+}}
 
+// The following platforms do not provide mbrtoc8 and c8rtomb so the tests fail
+// XFAIL: aix
+// XFAIL: freebsd
+// XFAIL: windows
+
 // mbrtoc16 not defined.
 // XFAIL: LIBCXX-PICOLIBC-FIXME
 
diff --git a/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
index 1d4a225668d80..8ae31a658a63c 100644
--- a/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
+++ b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
@@ -8,6 +8,12 @@
 
 // UNSUPPORTED: c++03
 
+// The following platforms do not provide mbrtoc8 and c8rtomb so the tests fail
+// XFAIL: aix
+// XFAIL: darwin
+// XFAIL: freebsd
+// XFAIL: windows
+
 #include <uchar.h>
 
 #include "test_macros.h"
diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 0cb81546665d4..ec71f1cda8662 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -669,6 +669,7 @@ def _getLocaleFlagsAction(cfg, locale, alts, members):
             """,
         ),
     ),
+    Feature(name="aix", when=lambda cfg: "_AIX" in compilerMacros(cfg)),
 ]
 
 # Add features representing the build host platform name.

>From 1735435f1c5358f1f2a364241f614131dadb90a0 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Wed, 17 Sep 2025 09:59:14 +0100
Subject: [PATCH 9/9] Add xfail for picolibc

---
 libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
index 8ae31a658a63c..c9868e6162f87 100644
--- a/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
+++ b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
@@ -13,6 +13,7 @@
 // XFAIL: darwin
 // XFAIL: freebsd
 // XFAIL: windows
+// XFAIL: LIBCXX-PICOLIBC-FIXME
 
 #include <uchar.h>
 



More information about the libcxx-commits mailing list