diff --git a/arm-software/embedded/patches/llvm-project/0001-libc-tests-with-picolibc-xfail-one-remaining-test.patch b/arm-software/embedded/patches/llvm-project/0001-libc-tests-with-picolibc-xfail-one-remaining-test.patch index b92d1efbbd7e..f128dbc55dd9 100644 --- a/arm-software/embedded/patches/llvm-project/0001-libc-tests-with-picolibc-xfail-one-remaining-test.patch +++ b/arm-software/embedded/patches/llvm-project/0001-libc-tests-with-picolibc-xfail-one-remaining-test.patch @@ -1,4 +1,4 @@ -From 623881f1ea465f9c1837981db143f7225108580a Mon Sep 17 00:00:00 2001 +From 835b3efcf5a21058dd897700fdab126781493f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Mon, 16 Oct 2023 11:35:48 +0200 Subject: [libc++] tests with picolibc: xfail one remaining test @@ -22,5 +22,5 @@ index d8eff69cb53f..e16048df722e 100644 void f() {} -- -2.39.5 (Apple Git-154) +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0002-libc-tests-with-picolibc-disable-large-tests.patch b/arm-software/embedded/patches/llvm-project/0002-libc-tests-with-picolibc-disable-large-tests.patch index 8f7a9ba68f07..8d6ed07c60a0 100644 --- a/arm-software/embedded/patches/llvm-project/0002-libc-tests-with-picolibc-disable-large-tests.patch +++ b/arm-software/embedded/patches/llvm-project/0002-libc-tests-with-picolibc-disable-large-tests.patch @@ -1,4 +1,4 @@ -From 8a0f8650d58f27ca32948554188b98c8978d1eb6 Mon Sep 17 00:00:00 2001 +From d26509789db1ef12299a530cda51357fcb020b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Wed, 15 Nov 2023 12:18:35 +0100 Subject: [libc++] tests with picolibc: disable large tests @@ -9,7 +9,7 @@ Subject: [libc++] tests with picolibc: disable large tests 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libcxx/cmake/caches/Armv7M-picolibc.cmake b/libcxx/cmake/caches/Armv7M-picolibc.cmake -index b5f9089308d2..0a83e75ceceb 100644 +index 0f8189b45728..9e1ae0832aee 100644 --- a/libcxx/cmake/caches/Armv7M-picolibc.cmake +++ b/libcxx/cmake/caches/Armv7M-picolibc.cmake @@ -18,6 +18,9 @@ set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") @@ -22,7 +22,7 @@ index b5f9089308d2..0a83e75ceceb 100644 set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXX_ENABLE_EXCEPTIONS ON CACHE BOOL "") set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE STRING "") -@@ -30,12 +33,16 @@ set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") +@@ -30,13 +33,17 @@ set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "") set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "") # Long tests are prohibitively slow when run via emulation. @@ -40,8 +40,9 @@ index b5f9089308d2..0a83e75ceceb 100644 +set(LIBUNWIND_TEST_PARAMS "long_tests=False;large_tests=False" CACHE STRING "") set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") find_program(QEMU_SYSTEM_ARM qemu-system-arm REQUIRED) + diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp -index ad131bb3a8a7..ac612c79f71c 100644 +index e9c74f70a094..dee394233d37 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -7,7 +7,7 @@ @@ -53,7 +54,6 @@ index ad131bb3a8a7..ac612c79f71c 100644 // This test exercises support for char array initializer lists added in // dd8b266ef. - // UNSUPPORTED: using-built-library-before-llvm-20 -- -2.39.5 (Apple Git-154) +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0003-Disable-failing-compiler-rt-test.patch b/arm-software/embedded/patches/llvm-project/0003-Disable-failing-compiler-rt-test.patch index 290bf4bfe3c4..dfe2de0ed797 100644 --- a/arm-software/embedded/patches/llvm-project/0003-Disable-failing-compiler-rt-test.patch +++ b/arm-software/embedded/patches/llvm-project/0003-Disable-failing-compiler-rt-test.patch @@ -1,4 +1,4 @@ -From 0f8dc80a7642430c8d02c36283766aeb5a59a331 Mon Sep 17 00:00:00 2001 +From 758eaf3c1f4d4fa3b0dc1f823133635e920fade1 Mon Sep 17 00:00:00 2001 From: Piotr Przybyla Date: Wed, 15 Nov 2023 16:04:24 +0000 Subject: Disable failing compiler-rt test @@ -18,5 +18,5 @@ index 2ff65a8b9ec3..98611a75e85f 100644 // RUN: %clang_builtins %s %librt -o %t && %run %t -- -2.39.5 (Apple Git-154) +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0004-libc-tests-with-picolibc-XFAIL-uses-of-atomics.patch b/arm-software/embedded/patches/llvm-project/0004-libc-tests-with-picolibc-XFAIL-uses-of-atomics.patch index 573a1a26a947..97e615b1ed6e 100644 --- a/arm-software/embedded/patches/llvm-project/0004-libc-tests-with-picolibc-XFAIL-uses-of-atomics.patch +++ b/arm-software/embedded/patches/llvm-project/0004-libc-tests-with-picolibc-XFAIL-uses-of-atomics.patch @@ -1,4 +1,4 @@ -From f5b5a95bd02f6d5bc6e80c238c2e8f7e08985d80 Mon Sep 17 00:00:00 2001 +From 295e2d01e88d3979aaae65214303d0a84243a4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Thu, 9 Nov 2023 15:25:14 +0100 Subject: [libc++] tests with picolibc: XFAIL uses of atomics @@ -88,10 +88,10 @@ index 000000000000..5ecc58f3e385 +if "has-no-atomics" in config.available_features: + config.unsupported = True diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py -index 735eb5ac949d..6ca4e8acb3f4 100644 +index e4b413deff4d..dd055f1312e5 100644 --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py -@@ -215,6 +215,21 @@ DEFAULT_FEATURES = [ +@@ -207,6 +207,21 @@ DEFAULT_FEATURES = [ """, ), ), @@ -114,5 +114,5 @@ index 735eb5ac949d..6ca4e8acb3f4 100644 Feature( name="32-bit-pointer", -- -2.39.5 (Apple Git-154) +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0005-libc-tests-with-picolibc-mark-two-more-large-tests.patch b/arm-software/embedded/patches/llvm-project/0005-libc-tests-with-picolibc-mark-two-more-large-tests.patch index 16cfb4a335fc..0c0986bbbea8 100644 --- a/arm-software/embedded/patches/llvm-project/0005-libc-tests-with-picolibc-mark-two-more-large-tests.patch +++ b/arm-software/embedded/patches/llvm-project/0005-libc-tests-with-picolibc-mark-two-more-large-tests.patch @@ -1,4 +1,4 @@ -From 0961af52ac015c26829b4dae7fd6879a0b633f44 Mon Sep 17 00:00:00 2001 +From 061b8165660a9e3f9d7b28f9a89edf9a5a7ac57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Wed, 22 Nov 2023 16:12:39 +0100 Subject: [libc++] tests with picolibc: mark two more large tests @@ -37,5 +37,5 @@ index 64a6a135adda..057301e6f868 100644 // bool // regex_search(BidirectionalIterator first, BidirectionalIterator last, -- -2.39.5 (Apple Git-154) +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0006-Define-_LIBCPP_HAS_C8RTOMB_MBRTOC8.patch b/arm-software/embedded/patches/llvm-project/0006-Define-_LIBCPP_HAS_C8RTOMB_MBRTOC8.patch index ac73bd5ee3d6..7ce968a49fe8 100644 --- a/arm-software/embedded/patches/llvm-project/0006-Define-_LIBCPP_HAS_C8RTOMB_MBRTOC8.patch +++ b/arm-software/embedded/patches/llvm-project/0006-Define-_LIBCPP_HAS_C8RTOMB_MBRTOC8.patch @@ -1,4 +1,4 @@ -From 9011c0e821d5b1563dc2dc6370f29c529e55f41f Mon Sep 17 00:00:00 2001 +From fac938223fca26f2cbdff7fa0208c8c58decb8e8 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Thu, 31 Oct 2024 09:58:34 +0000 Subject: Define _LIBCPP_HAS_C8RTOMB_MBRTOC8 @@ -23,10 +23,10 @@ govern picolibc version are in `picolibc.h`. 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/libcxx/include/__config b/libcxx/include/__config -index 1cf80a46686a..615433869a4e 100644 +index a866a7e65183..67ed2fbed1e3 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config -@@ -1021,21 +1021,8 @@ typedef __char32_t char32_t; +@@ -1029,21 +1029,8 @@ typedef __char32_t char32_t; // functions is gradually being added to existing C libraries. The conditions // below check for known C library versions and conditions under which these // functions are declared by the C library. @@ -51,5 +51,5 @@ index 1cf80a46686a..615433869a4e 100644 // There are a handful of public standard library types that are intended to // support CTAD but don't need any explicit deduction guides to do so. This -- -2.43.0 +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0007-libcxx-Remove-xfails-due-to-picolibc-s-support-for-c.patch b/arm-software/embedded/patches/llvm-project/0007-libcxx-Remove-xfails-due-to-picolibc-s-support-for-c.patch index 0929944a85bb..e993d7f976dd 100644 --- a/arm-software/embedded/patches/llvm-project/0007-libcxx-Remove-xfails-due-to-picolibc-s-support-for-c.patch +++ b/arm-software/embedded/patches/llvm-project/0007-libcxx-Remove-xfails-due-to-picolibc-s-support-for-c.patch @@ -1,4 +1,4 @@ -From 2c6b08baa20bb4a7e4a936ecf286a1c9e1f0f8c9 Mon Sep 17 00:00:00 2001 +From 119f253eb9c95c208cd55df4f2025e3d3904525b Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Thu, 31 Oct 2024 14:03:58 +0000 Subject: [libcxx] Remove xfails due to picolibc's support for char16_t and @@ -43,5 +43,5 @@ index 2076384deb2b..db00cbde3336 100644 #include -- -2.43.0 +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0008-library-order-workaround-for-597.patch b/arm-software/embedded/patches/llvm-project/0008-PATCH-Revert-order-of-libraries-and-update-tests.patch similarity index 98% rename from arm-software/embedded/patches/llvm-project/0008-library-order-workaround-for-597.patch rename to arm-software/embedded/patches/llvm-project/0008-PATCH-Revert-order-of-libraries-and-update-tests.patch index 6854fe3ff27e..e4bec8fa7f48 100644 --- a/arm-software/embedded/patches/llvm-project/0008-library-order-workaround-for-597.patch +++ b/arm-software/embedded/patches/llvm-project/0008-PATCH-Revert-order-of-libraries-and-update-tests.patch @@ -1,4 +1,4 @@ -From 3c25466248617c03c4db62504b226f82b568be5e Mon Sep 17 00:00:00 2001 +From aa109995a14c1f83b47fc0999c90539112cc471e Mon Sep 17 00:00:00 2001 From: Volodymyr Turanskyy Date: Thu, 19 Dec 2024 12:01:58 +0000 Subject: [PATCH] Revert order of libraries and update tests @@ -11,10 +11,10 @@ Subject: [PATCH] Revert order of libraries and update tests 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp -index eecaaa9a4293..7d07079b5dd4 100644 +index ffb1c6e34d60..6df60270bd74 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp -@@ -491,9 +491,8 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, +@@ -498,9 +498,8 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { @@ -238,5 +238,5 @@ index 6d6255ef5970..08c49a1beec0 100644 // Check that compiler-rt library without the arch filename suffix will -- -2.47.0 +2.34.1 diff --git a/arm-software/embedded/patches/llvm-project/0009-compiler-rt-Fix-tests-of-__aeabi_-idivmod-uidivmod-u.patch b/arm-software/embedded/patches/llvm-project/0009-compiler-rt-Fix-tests-of-__aeabi_-idivmod-uidivmod-u.patch new file mode 100644 index 000000000000..dcad9bf88cfe --- /dev/null +++ b/arm-software/embedded/patches/llvm-project/0009-compiler-rt-Fix-tests-of-__aeabi_-idivmod-uidivmod-u.patch @@ -0,0 +1,131 @@ +From 25f3995ae6fd70a1eb0fb804229ecb5848137f96 Mon Sep 17 00:00:00 2001 +From: Victor Campos +Date: Tue, 11 Feb 2025 09:49:56 +0000 +Subject: [compiler-rt] Fix tests of __aeabi_(idivmod|uidivmod|uldivmod) to + support big endian (#126277) + +This patch makes these functions' tests work in big endian mode: + - `__aeabi_idivmod`. + - `__aeabi_uidivmod`. + - `__aeabi_uldivmod`. + +The three functions return a struct containing two fields, quotient and +remainder, via *value in regs* calling convention. They differ in the +integer type of each field. + +In the tests of the first two, a 64-bit integer is used as the return +type of the call. And as consequence of the ABI rules for structs +(Composite Types), the quotient resides in `r0` and the remainder in +`r1` regardless of endianness. So, in order to access each component +from the 64-bit integer in the caller code, care must be taken to access +the correct bits as they do depend on endianness in this case. + +In the test of the third one, the caller code has inline assembly to +access the components. This assembly code assumed little endian, so it +had to be made flexible for big endian as well. + +`_YUGA_BIG_ENDIAN` is defined in `int_endianness.h`. It's a macro +internal to compiler-rt that's in theory compatible with more toolchains +than gcc and clang. +--- + .../builtins/Unit/arm/aeabi_idivmod_test.c | 11 +++++++++ + .../builtins/Unit/arm/aeabi_uidivmod_test.c | 11 +++++++++ + .../builtins/Unit/arm/aeabi_uldivmod_test.c | 23 ++++++++++++++++--- + 3 files changed, 42 insertions(+), 3 deletions(-) + +diff --git a/compiler-rt/test/builtins/Unit/arm/aeabi_idivmod_test.c b/compiler-rt/test/builtins/Unit/arm/aeabi_idivmod_test.c +index ff767d754eb9..e4953bf51b03 100644 +--- a/compiler-rt/test/builtins/Unit/arm/aeabi_idivmod_test.c ++++ b/compiler-rt/test/builtins/Unit/arm/aeabi_idivmod_test.c +@@ -14,8 +14,19 @@ int test__aeabi_idivmod(si_int a, si_int b, + { + si_int rem; + du_int ret = __aeabi_idivmod(a, b); ++ // __aeabi_idivmod actually returns a struct { quotient; remainder; } using ++ // value_in_regs calling convention. Due to the ABI rules, struct fields ++ // come in the same order regardless of endianness. However since the ++ // result is received here as a 64-bit integer, in which endianness does ++ // matter, the position of each component (quotient and remainder) varies ++ // depending on endianness. ++# if _YUGA_BIG_ENDIAN ++ rem = ret & 0xFFFFFFFF; ++ si_int result = ret >> 32; ++# else + rem = ret >> 32; + si_int result = ret & 0xFFFFFFFF; ++# endif + if (result != expected_result) { + printf("error in __aeabi_idivmod: %d / %d = %d, expected %d\n", + a, b, result, expected_result); +diff --git a/compiler-rt/test/builtins/Unit/arm/aeabi_uidivmod_test.c b/compiler-rt/test/builtins/Unit/arm/aeabi_uidivmod_test.c +index de5a43d5b814..a507267c4460 100644 +--- a/compiler-rt/test/builtins/Unit/arm/aeabi_uidivmod_test.c ++++ b/compiler-rt/test/builtins/Unit/arm/aeabi_uidivmod_test.c +@@ -13,8 +13,19 @@ int test__aeabi_uidivmod(su_int a, su_int b, + su_int expected_result, su_int expected_rem) + { + du_int ret = __aeabi_uidivmod(a, b); ++ // __aeabi_uidivmod actually returns a struct { quotient; remainder; } ++ // using value_in_regs calling convention. Due to the ABI rules, struct ++ // fields come in the same order regardless of endianness. However since ++ // the result is received here as a 64-bit integer, in which endianness ++ // does matter, the position of each component (quotient and remainder) ++ // varies depending on endianness. ++# if _YUGA_BIG_ENDIAN ++ su_int rem = ret & 0xFFFFFFFF; ++ si_int result = ret >> 32; ++# else + su_int rem = ret >> 32; + si_int result = ret & 0xFFFFFFFF; ++# endif + + if (result != expected_result) { + printf("error in __aeabi_uidivmod: %u / %u = %u, expected %u\n", +diff --git a/compiler-rt/test/builtins/Unit/arm/aeabi_uldivmod_test.c b/compiler-rt/test/builtins/Unit/arm/aeabi_uldivmod_test.c +index 98611a75e85f..2c04061a2ef6 100644 +--- a/compiler-rt/test/builtins/Unit/arm/aeabi_uldivmod_test.c ++++ b/compiler-rt/test/builtins/Unit/arm/aeabi_uldivmod_test.c +@@ -14,20 +14,37 @@ COMPILER_RT_ABI void /* __value_in_regs */ __aeabi_uldivmod(du_int a, du_int b); + int test_aeabi_uldivmod(du_int a, du_int b, du_int expected_q, du_int expected_r) + { + du_int q, r; ++ // __aeabi_uldivmod returns a struct { quotient; remainder; } using ++ // value_in_regs calling convention. Each field is a 64-bit integer, so the ++ // quotient resides in r0 and r1, while the remainder in r2 and r3. The ++ // byte order however depends on the endianness. + __asm__( ++# if _YUGA_BIG_ENDIAN ++ "movs r1, %Q[a] \n" ++ "movs r0, %R[a] \n" ++ "movs r3, %Q[b] \n" ++ "movs r2, %R[b] \n" ++# else + "movs r0, %Q[a] \n" + "movs r1, %R[a] \n" + "movs r2, %Q[b] \n" + "movs r3, %R[b] \n" ++# endif + "bl __aeabi_uldivmod \n" ++# if _YUGA_BIG_ENDIAN ++ "movs %Q[q], r1\n" ++ "movs %R[q], r0\n" ++ "movs %Q[r], r3\n" ++ "movs %R[r], r2\n" ++# else + "movs %Q[q], r0\n" + "movs %R[q], r1\n" + "movs %Q[r], r2\n" + "movs %R[r], r3\n" +- : [q] "=r" (q), [r] "=r"(r) ++# endif ++ : [q] "=r"(q), [r] "=r"(r) + : [a] "r"(a), [b] "r"(b) +- : "lr", "r0", "r1", "r2", "r3" +- ); ++ : "lr", "r0", "r1", "r2", "r3"); + if (q != expected_q || r != expected_r) + printf("error in aeabi_uldivmod: %llX / %llX = %llX, R = %llX, expected %llX, %llX\n", + a, b, q, r, expected_q, expected_r); +-- +2.34.1 + diff --git a/arm-software/embedded/patches/llvm-project/0010-compiler-rt-Add-support-for-big-endian-for-Arm-s-__n.patch b/arm-software/embedded/patches/llvm-project/0010-compiler-rt-Add-support-for-big-endian-for-Arm-s-__n.patch new file mode 100644 index 000000000000..c8e99b18b9d1 --- /dev/null +++ b/arm-software/embedded/patches/llvm-project/0010-compiler-rt-Add-support-for-big-endian-for-Arm-s-__n.patch @@ -0,0 +1,36 @@ +From 2c5da3adea204dc5e6fe4d990a34571a04e9ecb4 Mon Sep 17 00:00:00 2001 +From: Victor Campos +Date: Mon, 17 Feb 2025 11:43:36 +0000 +Subject: [compiler-rt] Add support for big endian for Arm's __negdf2vfp + (#127096) + +In soft floating-point ABI, this function takes the double argument as a +pair of registers r0 and r1. + +The ordering of these two registers follow the endianness rules, +therefore the register on which the bit flipping must happen depends on +the endianness. +--- + compiler-rt/lib/builtins/arm/negdf2vfp.S | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/compiler-rt/lib/builtins/arm/negdf2vfp.S b/compiler-rt/lib/builtins/arm/negdf2vfp.S +index b7cf91877e38..329c6de757f6 100644 +--- a/compiler-rt/lib/builtins/arm/negdf2vfp.S ++++ b/compiler-rt/lib/builtins/arm/negdf2vfp.S +@@ -20,7 +20,11 @@ DEFINE_COMPILERRT_FUNCTION(__negdf2vfp) + #if defined(COMPILER_RT_ARMHF_TARGET) + vneg.f64 d0, d0 + #else +- eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair ++#if _YUGA_BIG_ENDIAN ++ eor r0, r0, #0x80000000 // flip sign bit on double in r0/r1 pair ++#else ++ eor r1, r1, #0x80000000 // flip sign bit on double in r0/r1 pair ++#endif + #endif + bx lr + END_COMPILERRT_FUNCTION(__negdf2vfp) +-- +2.34.1 + diff --git a/arm-software/embedded/patches/llvm-project/0011-libcxx-Work-around-picolibc-argv-handling-in-tests.-.patch b/arm-software/embedded/patches/llvm-project/0011-libcxx-Work-around-picolibc-argv-handling-in-tests.-.patch new file mode 100644 index 000000000000..5827b2631574 --- /dev/null +++ b/arm-software/embedded/patches/llvm-project/0011-libcxx-Work-around-picolibc-argv-handling-in-tests.-.patch @@ -0,0 +1,96 @@ +From 2bd9e642a2f585b9042b3b472ddb387c838a94d6 Mon Sep 17 00:00:00 2001 +From: Simon Tatham +Date: Fri, 21 Feb 2025 09:08:53 +0000 +Subject: [libcxx] Work around picolibc argv handling in tests. (#127662) + +This fixes some test failures when the libcxx tests are run against an +up-to-date picolibc on embedded Arm, because those tests depend on an +unsupported locale but the `hasAnyLocale` preliminary check wrongly +concluded that the locale _was_ supported. + +`hasAnyLocale` passes a set of locale strings to a test program via the +command line, and checks if the libc under test reports that any of the +locales can be successfully set via setlocale(). In some invocations one +of the locale names contains a space, e.g. the Windows-style locale name +"English_United States.1252". + +Unfortunately picolibc's crt0, when running under Arm semihosting, +fetches the single command string from the host and then splits it up at +spaces without implementing any kind of quoting. So it simply isn't +possible to get a space into an argv word. As a result, we end up +testing for the locale (in this example) "English_United". In up-to-date +versions of picolibc, this is actually accepted, since it contains no +objectionable character set specification (or indeed any at all). So the +lit check wrongly concludes that libc supports that locale, and enables +some locale tests, which fail. + +This patch works around the issue entirely within `hasAnyLocale()`, by +abandoning the use of argv completely, and instead encoding the list of +locales to check as an array of strings inside the test program. +--- + libcxx/utils/libcxx/test/dsl.py | 31 ++++++++++++++++++++++++------- + 1 file changed, 24 insertions(+), 7 deletions(-) + +diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py +index 7ff4be0ee7cf..9a97e61efbe7 100644 +--- a/libcxx/utils/libcxx/test/dsl.py ++++ b/libcxx/utils/libcxx/test/dsl.py +@@ -9,7 +9,6 @@ + import os + import pickle + import platform +-import shlex + import shutil + import tempfile + +@@ -274,23 +273,41 @@ def hasAnyLocale(config, locales): + %{exec} -- this means that the command may be executed on a remote host + depending on the %{exec} substitution. + """ +- program = """ ++ ++ # Convert the locale names into C string literals. We expect all currently ++ # known locale names to be printable ASCII and not contain awkward ++ # characters like \ or ", so this should be trivial. ++ assert all( ++ 0x20 <= ord(ch) <= 0x7E and ch not in {'"', "\\"} ++ for locale in locales ++ for ch in locale ++ ) ++ name_string_literals = ", ".join('"' + locale + '"' for locale in locales) ++ ++ program = ( ++ """ + #include + #if defined(_LIBCPP_VERSION) && !_LIBCPP_HAS_LOCALIZATION + int main(int, char**) { return 1; } + #else + #include +- int main(int argc, char** argv) { +- for (int i = 1; i < argc; i++) { +- if (::setlocale(LC_ALL, argv[i]) != NULL) { ++ static const char *const test_locale_names[] = { ++ """ ++ + name_string_literals ++ + """, nullptr, ++ }; ++ int main() { ++ for (size_t i = 0; test_locale_names[i]; i++) { ++ if (::setlocale(LC_ALL, test_locale_names[i]) != NULL) { + return 0; + } + } + return 1; + } + #endif +- """ +- return programSucceeds(config, program, args=[shlex.quote(l) for l in locales]) ++ """ ++ ) ++ return programSucceeds(config, program) + + + @_memoizeExpensiveOperation(lambda c, flags="": (c.substitutions, c.environment, flags)) +-- +2.34.1 +