[libcxx-commits] [libcxx] [llvm] [libc++] Remove the need for `uselocale()` (PR #120158)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Dec 19 09:08:01 PST 2024


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/120158

>From 9e4081e2e623fb8ca96bbef176c0e7e2c686d8d1 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 11 Nov 2024 14:45:06 -0500
Subject: [PATCH 1/4] [libc++] Remove the need for `uselocale()`

Instead of requiring `uselocale()` as part of the base locale API,
define __locale_guard in the few places that need it directly, without
making __locale_guard part of the base API.

In practice, most mainstream platforms never used __locale_guard, so
they also didn't need to define uselocale(), and after this patch they
actually don't define it anymore.
---
 libcxx/include/CMakeLists.txt                 |  1 -
 libcxx/include/__locale_dir/locale_base_api.h |  6 --
 .../locale_base_api/bsd_locale_fallbacks.h    | 16 +++-
 libcxx/include/__locale_dir/locale_guard.h    | 78 -------------------
 .../include/__locale_dir/support/bsd_like.h   |  2 -
 libcxx/include/__locale_dir/support/windows.h | 42 +++++++++-
 .../__support/xlocale/__nop_locale_mgmt.h     |  2 -
 libcxx/include/module.modulemap               |  2 -
 libcxx/src/iostream.cpp                       |  6 +-
 libcxx/src/support/win32/locale_win32.cpp     | 29 ++++---
 10 files changed, 67 insertions(+), 117 deletions(-)
 delete mode 100644 libcxx/include/__locale_dir/locale_guard.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ba392e5883ff39..b5bbfbe7d3a233 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -503,7 +503,6 @@ set(files
   __locale_dir/locale_base_api/ibm.h
   __locale_dir/locale_base_api/musl.h
   __locale_dir/locale_base_api/openbsd.h
-  __locale_dir/locale_guard.h
   __locale_dir/pad_and_output.h
   __locale_dir/support/apple.h
   __locale_dir/support/bsd_like.h
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 7e3c205c04a780..c8097beb9052df 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -23,14 +23,12 @@
 // Variadic functions may be implemented as templates with a parameter pack instead
 // of C-style variadic functions.
 //
-// TODO: I think __uselocale() is not necessary if we refactor a bit.
 // TODO: __localeconv shouldn't take a reference, but the Windows implementation doesn't allow copying __locale_t
 //
 // Locale management
 // -----------------
 // namespace __locale {
 //  using __locale_t = implementation-defined;
-//  __locale_t  __uselocale(__locale_t);
 //  __locale_t  __newlocale(int, const char*, __locale_t);
 //  void        __freelocale(__locale_t);
 //  lconv*      __localeconv(__locale_t&);
@@ -139,10 +137,6 @@ namespace __locale {
 //
 using __locale_t = locale_t;
 
-#  ifndef _LIBCPP_MSVCRT_LIKE
-inline _LIBCPP_HIDE_FROM_ABI __locale_t __uselocale(__locale_t __loc) { return uselocale(__loc); }
-#  endif
-
 inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) {
   return newlocale(__category_mask, __name, __loc);
 }
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index d514bdfaace903..b62a1b737e97f9 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -14,8 +14,6 @@
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 
 #include <locale.h>
-
-#include <__locale_dir/locale_guard.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,6 +28,20 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+struct __locale_guard {
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+
+  _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
+    if (__old_loc_)
+      ::uselocale(__old_loc_);
+  }
+
+  locale_t __old_loc_;
+
+  __locale_guard(__locale_guard const&)            = delete;
+  __locale_guard& operator=(__locale_guard const&) = delete;
+};
+
 inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) {
   __locale_guard __current(__l);
   return MB_CUR_MAX;
diff --git a/libcxx/include/__locale_dir/locale_guard.h b/libcxx/include/__locale_dir/locale_guard.h
deleted file mode 100644
index 93d38334f31323..00000000000000
--- a/libcxx/include/__locale_dir/locale_guard.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___LOCALE_DIR_LOCALE_GUARD_H
-#define _LIBCPP___LOCALE_DIR_LOCALE_GUARD_H
-
-#include <__config>
-#include <__locale> // for locale_t
-#include <clocale>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if defined(_LIBCPP_MSVCRT_LIKE)
-struct __locale_guard {
-  __locale_guard(__locale::__locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
-    // Setting the locale can be expensive even when the locale given is
-    // already the current locale, so do an explicit check to see if the
-    // current locale is already the one we want.
-    const char* __lc = __setlocale(nullptr);
-    // If every category is the same, the locale string will simply be the
-    // locale name, otherwise it will be a semicolon-separated string listing
-    // each category.  In the second case, we know at least one category won't
-    // be what we want, so we only have to check the first case.
-    if (std::strcmp(__l.__get_locale(), __lc) != 0) {
-      __locale_all = _strdup(__lc);
-      if (__locale_all == nullptr)
-        __throw_bad_alloc();
-      __setlocale(__l.__get_locale());
-    }
-  }
-  ~__locale_guard() {
-    // The CRT documentation doesn't explicitly say, but setlocale() does the
-    // right thing when given a semicolon-separated list of locale settings
-    // for the different categories in the same format as returned by
-    // setlocale(LC_ALL, nullptr).
-    if (__locale_all != nullptr) {
-      __setlocale(__locale_all);
-      free(__locale_all);
-    }
-    _configthreadlocale(__status);
-  }
-  static const char* __setlocale(const char* __locale) {
-    const char* __new_locale = setlocale(LC_ALL, __locale);
-    if (__new_locale == nullptr)
-      __throw_bad_alloc();
-    return __new_locale;
-  }
-  int __status;
-  char* __locale_all = nullptr;
-};
-#else
-struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
-
-  _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
-    if (__old_loc_)
-      uselocale(__old_loc_);
-  }
-
-  locale_t __old_loc_;
-
-  __locale_guard(__locale_guard const&)            = delete;
-  __locale_guard& operator=(__locale_guard const&) = delete;
-};
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___LOCALE_DIR_LOCALE_GUARD_H
diff --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h
index cce6de64673b0e..da31aeaf3c58e3 100644
--- a/libcxx/include/__locale_dir/support/bsd_like.h
+++ b/libcxx/include/__locale_dir/support/bsd_like.h
@@ -38,8 +38,6 @@ namespace __locale {
 //
 using __locale_t = ::locale_t;
 
-inline _LIBCPP_HIDE_FROM_ABI __locale_t __uselocale(__locale_t __loc) { return ::uselocale(__loc); }
-
 inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
   return ::newlocale(__category_mask, __locale, __base);
 }
diff --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h
index fd6aab8de9ac8d..4ba7ccfeb585a2 100644
--- a/libcxx/include/__locale_dir/support/windows.h
+++ b/libcxx/include/__locale_dir/support/windows.h
@@ -39,6 +39,44 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
+struct __locale_guard {
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
+    // Setting the locale can be expensive even when the locale given is
+    // already the current locale, so do an explicit check to see if the
+    // current locale is already the one we want.
+    const char* __lc = __setlocale(nullptr);
+    // If every category is the same, the locale string will simply be the
+    // locale name, otherwise it will be a semicolon-separated string listing
+    // each category.  In the second case, we know at least one category won't
+    // be what we want, so we only have to check the first case.
+    if (std::strcmp(__l.__get_locale(), __lc) != 0) {
+      __locale_all = _strdup(__lc);
+      if (__locale_all == nullptr)
+        __throw_bad_alloc();
+      __setlocale(__l.__get_locale());
+    }
+  }
+  _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
+    // The CRT documentation doesn't explicitly say, but setlocale() does the
+    // right thing when given a semicolon-separated list of locale settings
+    // for the different categories in the same format as returned by
+    // setlocale(LC_ALL, nullptr).
+    if (__locale_all != nullptr) {
+      __setlocale(__locale_all);
+      free(__locale_all);
+    }
+    _configthreadlocale(__status);
+  }
+  _LIBCPP_HIDE_FROM_ABI static const char* __setlocale(const char* __locale) {
+    const char* __new_locale = setlocale(LC_ALL, __locale);
+    if (__new_locale == nullptr)
+      __throw_bad_alloc();
+    return __new_locale;
+  }
+  int __status;
+  char* __locale_all = nullptr;
+};
+
 class __lconv_storage {
 public:
   __lconv_storage(const lconv* __lc_input) {
@@ -149,10 +187,6 @@ class __locale_t {
   __lconv_storage* __lc_ = nullptr;
 };
 
-// __uselocale can't be implemented on Windows because Windows allows partial modification
-// of thread-local locale and so _get_current_locale() returns a copy while __uselocale does
-// not create any copies. We can still implement RAII even without __uselocale though.
-__locale_t __uselocale(__locale_t) = delete;
 _LIBCPP_EXPORTED_FROM_ABI __locale_t __newlocale(int __mask, const char* __locale, __locale_t __base);
 inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::_free_locale(__loc); }
 _LIBCPP_EXPORTED_FROM_ABI lconv* __localeconv(__locale_t& __loc);
diff --git a/libcxx/include/__support/xlocale/__nop_locale_mgmt.h b/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
index 5aaf3eaa6441d9..eabe169cc4bc8c 100644
--- a/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
+++ b/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
@@ -21,8 +21,6 @@ inline _LIBCPP_HIDE_FROM_ABI void freelocale(locale_t) {}
 
 inline _LIBCPP_HIDE_FROM_ABI locale_t newlocale(int, const char*, locale_t) { return nullptr; }
 
-inline _LIBCPP_HIDE_FROM_ABI locale_t uselocale(locale_t) { return nullptr; }
-
 #define LC_COLLATE_MASK (1 << LC_COLLATE)
 #define LC_CTYPE_MASK (1 << LC_CTYPE)
 #define LC_MESSAGES_MASK (1 << LC_MESSAGES)
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index ba45af273f4842..bd815a66ea6be0 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1466,8 +1466,6 @@ module std [system] {
 
   module locale {
     header "locale"
-
-    module locale_guard   { header "__locale_dir/locale_guard.h" }
     module pad_and_output { header "__locale_dir/pad_and_output.h" }
 
     module support {
diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index ee33f4bae6d891..6db02d56037947 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -11,10 +11,6 @@
 #include <new>
 #include <string>
 
-#ifdef _LIBCPP_MSVCRT_LIKE
-#  include <__locale_dir/locale_guard.h>
-#endif
-
 #define _str(s) #s
 #define str(s) _str(s)
 #define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
@@ -109,7 +105,7 @@ static void force_locale_initialization() {
   static bool once = []() {
     auto loc = __locale::__newlocale(LC_ALL_MASK, "C", 0);
     {
-      __locale_guard g(loc); // forces initialization of locale TLS
+      __locale::__locale_guard g(loc); // forces initialization of locale TLS
       ((void)g);
     }
     __locale::__freelocale(loc);
diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index 0a537d6997ca23..c5d7af41c3e7b1 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <__locale_dir/locale_guard.h>
 #include <__locale_dir/support/windows.h>
 #include <clocale> // std::localeconv() & friends
 #include <cstdarg> // va_start & friends
@@ -28,7 +27,7 @@ __locale_t __newlocale(int /*mask*/, const char* locale, __locale_t /*base*/) {
 }
 
 lconv* __localeconv(__locale_t& loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   lconv* lc = std::localeconv();
   if (!lc)
     return lc;
@@ -40,12 +39,12 @@ lconv* __localeconv(__locale_t& loc) {
 //
 #if !defined(_LIBCPP_MSVCRT)
 float __strtof(const char* nptr, char** endptr, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::strtof(nptr, endptr);
 }
 
 long double __strtold(const char* nptr, char** endptr, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::strtold(nptr, endptr);
 }
 #endif
@@ -55,7 +54,7 @@ long double __strtold(const char* nptr, char** endptr, __locale_t loc) {
 //
 #if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800
 size_t __strftime(char* ret, size_t n, const char* format, const struct tm* tm, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::strftime(ret, n, format, tm);
 }
 #endif
@@ -67,18 +66,18 @@ decltype(MB_CUR_MAX) __mb_len_max(__locale_t __l) {
 #if defined(_LIBCPP_MSVCRT)
   return ::___mb_cur_max_l_func(__l);
 #else
-  std::__locale_guard __current(__l);
+  __locale_guard __current(__l);
   return MB_CUR_MAX;
 #endif
 }
 
 wint_t __btowc(int c, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::btowc(c);
 }
 
 int __wctob(wint_t c, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::wctob(c);
 }
 
@@ -88,12 +87,12 @@ size_t __wcsnrtombs(char* __restrict dst,
                     size_t len,
                     mbstate_t* __restrict ps,
                     __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return ::wcsnrtombs(dst, src, nwc, len, ps);
 }
 
 size_t __wcrtomb(char* __restrict s, wchar_t wc, mbstate_t* __restrict ps, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::wcrtomb(s, wc, ps);
 }
 
@@ -103,24 +102,24 @@ size_t __mbsnrtowcs(wchar_t* __restrict dst,
                     size_t len,
                     mbstate_t* __restrict ps,
                     __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return ::mbsnrtowcs(dst, src, nms, len, ps);
 }
 
 size_t
 __mbrtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n, mbstate_t* __restrict ps, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::mbrtowc(pwc, s, n, ps);
 }
 
 size_t __mbrlen(const char* __restrict s, size_t n, mbstate_t* __restrict ps, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::mbrlen(s, n, ps);
 }
 
 size_t __mbsrtowcs(
     wchar_t* __restrict dst, const char** __restrict src, size_t len, mbstate_t* __restrict ps, __locale_t loc) {
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return std::mbsrtowcs(dst, src, len, ps);
 }
 
@@ -132,7 +131,7 @@ int __snprintf(char* ret, size_t n, __locale_t loc, const char* format, ...) {
   int result = ::__stdio_common_vsprintf(
       _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, ret, n, format, loc, ap);
 #else
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   _LIBCPP_DIAGNOSTIC_PUSH
   _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
   int result = std::vsnprintf(ret, n, format, ap);

>From 1870001a64cd3913f9e8218dcbe0d58ae8b75574 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 19 Dec 2024 11:09:42 -0500
Subject: [PATCH 2/4] Try fixing Windows issue

---
 libcxx/include/__locale_dir/support/windows.h | 77 ++++++++++---------
 1 file changed, 39 insertions(+), 38 deletions(-)

diff --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h
index 4ba7ccfeb585a2..81fbd74af9c5f7 100644
--- a/libcxx/include/__locale_dir/support/windows.h
+++ b/libcxx/include/__locale_dir/support/windows.h
@@ -39,44 +39,6 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
-struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
-    // Setting the locale can be expensive even when the locale given is
-    // already the current locale, so do an explicit check to see if the
-    // current locale is already the one we want.
-    const char* __lc = __setlocale(nullptr);
-    // If every category is the same, the locale string will simply be the
-    // locale name, otherwise it will be a semicolon-separated string listing
-    // each category.  In the second case, we know at least one category won't
-    // be what we want, so we only have to check the first case.
-    if (std::strcmp(__l.__get_locale(), __lc) != 0) {
-      __locale_all = _strdup(__lc);
-      if (__locale_all == nullptr)
-        __throw_bad_alloc();
-      __setlocale(__l.__get_locale());
-    }
-  }
-  _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
-    // The CRT documentation doesn't explicitly say, but setlocale() does the
-    // right thing when given a semicolon-separated list of locale settings
-    // for the different categories in the same format as returned by
-    // setlocale(LC_ALL, nullptr).
-    if (__locale_all != nullptr) {
-      __setlocale(__locale_all);
-      free(__locale_all);
-    }
-    _configthreadlocale(__status);
-  }
-  _LIBCPP_HIDE_FROM_ABI static const char* __setlocale(const char* __locale) {
-    const char* __new_locale = setlocale(LC_ALL, __locale);
-    if (__new_locale == nullptr)
-      __throw_bad_alloc();
-    return __new_locale;
-  }
-  int __status;
-  char* __locale_all = nullptr;
-};
-
 class __lconv_storage {
 public:
   __lconv_storage(const lconv* __lc_input) {
@@ -322,6 +284,45 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __s
 _LIBCPP_DIAGNOSTIC_POP
 #undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
 
+struct __locale_guard {
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(__locale_t __l)
+      : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
+    // Setting the locale can be expensive even when the locale given is
+    // already the current locale, so do an explicit check to see if the
+    // current locale is already the one we want.
+    const char* __lc = __setlocale(nullptr);
+    // If every category is the same, the locale string will simply be the
+    // locale name, otherwise it will be a semicolon-separated string listing
+    // each category.  In the second case, we know at least one category won't
+    // be what we want, so we only have to check the first case.
+    if (std::strcmp(__l.__get_locale(), __lc) != 0) {
+      __locale_all = _strdup(__lc);
+      if (__locale_all == nullptr)
+        __throw_bad_alloc();
+      __setlocale(__l.__get_locale());
+    }
+  }
+  _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
+    // The CRT documentation doesn't explicitly say, but setlocale() does the
+    // right thing when given a semicolon-separated list of locale settings
+    // for the different categories in the same format as returned by
+    // setlocale(LC_ALL, nullptr).
+    if (__locale_all != nullptr) {
+      __setlocale(__locale_all);
+      free(__locale_all);
+    }
+    _configthreadlocale(__status);
+  }
+  _LIBCPP_HIDE_FROM_ABI static const char* __setlocale(const char* __locale) {
+    const char* __new_locale = setlocale(LC_ALL, __locale);
+    if (__new_locale == nullptr)
+      __throw_bad_alloc();
+    return __new_locale;
+  }
+  int __status;
+  char* __locale_all = nullptr;
+};
+
 } // namespace __locale
 _LIBCPP_END_NAMESPACE_STD
 

>From a520e434e3718eb87cfee4f4d3964c344104cb45 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 19 Dec 2024 11:10:16 -0500
Subject: [PATCH 3/4] TEMP: Only run the Windows jobs

---
 .github/workflows/libcxx-build-and-test.yaml | 192 -------------------
 1 file changed, 192 deletions(-)

diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml
index cba8afbb54f0f0..d25e8e1ab61976 100644
--- a/.github/workflows/libcxx-build-and-test.yaml
+++ b/.github/workflows/libcxx-build-and-test.yaml
@@ -34,200 +34,8 @@ concurrency:
   cancel-in-progress: true
 
 jobs:
-  stage1:
-    if: github.repository_owner == 'llvm'
-    runs-on: libcxx-self-hosted-linux
-    container: ghcr.io/llvm/libcxx-linux-builder:0fd6f684b9c84c32d6cbfd9742402e788b2879f1
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      matrix:
-        config: [
-          'generic-cxx03',
-          'generic-cxx26',
-          'generic-modules'
-        ]
-        cc: [  'clang-19' ]
-        cxx: [ 'clang++-19' ]
-        include:
-          - config: 'generic-gcc'
-            cc: 'gcc-14'
-            cxx: 'g++-14'
-    steps:
-      - uses: actions/checkout at v4
-      - name: ${{ matrix.config }}.${{ matrix.cxx }}
-        run: libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-        env:
-          CC: ${{ matrix.cc }}
-          CXX: ${{ matrix.cxx }}
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()
-        with:
-          name: ${{ matrix.config }}-${{ matrix.cxx }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeConfigureLog.yaml
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-  stage2:
-    if: github.repository_owner == 'llvm'
-    runs-on: libcxx-self-hosted-linux
-    container: ghcr.io/llvm/libcxx-linux-builder:0fd6f684b9c84c32d6cbfd9742402e788b2879f1
-    needs: [ stage1 ]
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      matrix:
-        config: [
-          'generic-cxx11',
-          'generic-cxx14',
-          'generic-cxx17',
-          'generic-cxx20',
-          'generic-cxx23'
-        ]
-        cc: [ 'clang-19' ]
-        cxx: [ 'clang++-19' ]
-        include:
-          - config: 'generic-gcc-cxx11'
-            cc: 'gcc-14'
-            cxx: 'g++-14'
-          - config: 'generic-cxx23'
-            cc: 'clang-17'
-            cxx: 'clang++-17'
-          - config: 'generic-cxx26'
-            cc: 'clang-18'
-            cxx: 'clang++-18'
-    steps:
-      - uses: actions/checkout at v4
-      - name: ${{ matrix.config }}
-        run: libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-        env:
-          CC: ${{ matrix.cc }}
-          CXX: ${{ matrix.cxx }}
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()  # Upload artifacts even if the build or test suite fails
-        with:
-          name: ${{ matrix.config }}-${{ matrix.cxx }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeConfigureLog.yaml
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-  stage3:
-    if: github.repository_owner == 'llvm'
-    needs: [ stage1, stage2 ]
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      max-parallel: 8
-      matrix:
-        config: [
-          'generic-abi-unstable',
-          'generic-hardening-mode-debug',
-          'generic-hardening-mode-extensive',
-          'generic-hardening-mode-fast',
-          'generic-hardening-mode-fast-with-abi-breaks',
-          'generic-merged',
-          'generic-modules-lsv',
-          'generic-no-exceptions',
-          'generic-no-experimental',
-          'generic-no-filesystem',
-          'generic-no-localization',
-          'generic-no-terminal',
-          'generic-no-random_device',
-          'generic-no-threads',
-          'generic-no-tzdb',
-          'generic-no-unicode',
-          'generic-no-wide-characters',
-          'generic-no-rtti',
-          'generic-optimized-speed',
-          'generic-static',
-          'bootstrapping-build'
-        ]
-        machine: [ 'libcxx-self-hosted-linux' ]
-        include:
-        - config: 'generic-cxx26'
-          machine: libcxx-self-hosted-linux
-        - config: 'generic-asan'
-          machine: libcxx-self-hosted-linux
-        - config: 'generic-tsan'
-          machine: libcxx-self-hosted-linux
-        - config: 'generic-ubsan'
-          machine: libcxx-self-hosted-linux
-        # Use a larger machine for MSAN to avoid timeout and memory allocation issues.
-        - config: 'generic-msan'
-          machine: libcxx-self-hosted-linux
-    runs-on: ${{ matrix.machine }}
-    container: ghcr.io/llvm/libcxx-linux-builder:0fd6f684b9c84c32d6cbfd9742402e788b2879f1
-    steps:
-      - uses: actions/checkout at v4
-      - name: ${{ matrix.config }}
-        run: libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-        env:
-          CC: clang-19
-          CXX: clang++-19
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()
-        with:
-          name: ${{ matrix.config }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeConfigureLog.yaml
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-
-  macos:
-    needs: [ stage1 ]
-    strategy:
-      fail-fast: false
-      matrix:
-        include:
-        - config: generic-cxx03
-          os: macos-15
-        - config: generic-cxx23
-          os: macos-15
-        - config: generic-modules
-          os: macos-15
-        - config: apple-configuration
-          os: macos-15
-        - config: apple-system
-          os: macos-13
-        - config: apple-system-hardened
-          os: macos-13
-    runs-on: ${{ matrix.os }}
-    steps:
-      - uses: actions/checkout at v4
-      - uses: maxim-lobanov/setup-xcode at v1
-        with:
-          xcode-version: 'latest'
-      - uses: seanmiddleditch/gha-setup-ninja at master
-      - name: Build and test
-        run: |
-          python3 -m venv .venv
-          source .venv/bin/activate
-          python -m pip install psutil
-          bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()  # Upload artifacts even if the build or test suite fails
-        with:
-          name: macos-${{ matrix.config }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeConfigureLog.yaml
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-
   windows:
     runs-on: windows-2022
-    needs: [ stage1 ]
     strategy:
       fail-fast: false
       matrix:

>From f7de6767a3e64e53b78f70d35b5e9352f1d536ae Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 19 Dec 2024 12:07:43 -0500
Subject: [PATCH 4/4] Rename forgotten __locale_guard

---
 libcxx/src/support/win32/locale_win32.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index c5d7af41c3e7b1..ec2dd7f36ec709 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -177,7 +177,7 @@ int __libcpp_vasprintf(char** sptr, const char* __restrict format, va_list ap) {
 int __asprintf(char** ret, __locale_t loc, const char* format, ...) {
   va_list ap;
   va_start(ap, format);
-  std::__locale_guard __current(loc);
+  __locale_guard __current(loc);
   return __libcpp_vasprintf(ret, format, ap);
 }
 



More information about the libcxx-commits mailing list