[libcxx-commits] [libcxx] [libcxxabi] varconst/hardening semantics introduce (PR #148268)
Konstantin Varlamov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jul 12 20:06:04 PDT 2025
https://github.com/var-const updated https://github.com/llvm/llvm-project/pull/148268
>From 6708ebf6020c59a4832aac95cb9524d533798100 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Fri, 11 Jul 2025 10:17:36 -0700
Subject: [PATCH 01/14] [libc++][hardening][NFC] Introduce
`_LIBCPP_VERBOSE_TRAP` macro.
Split out the calls to `__builtin_verbose_trap` into a separate header.
This is just a refactoring to make the code a bit more structured.
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__verbose_trap | 36 +++++++++++++++++++
.../vendor/llvm/default_assertion_handler.in | 14 ++------
3 files changed, 39 insertions(+), 12 deletions(-)
create mode 100644 libcxx/include/__verbose_trap
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index c8e6d28584623..f79edc9e32599 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -944,6 +944,7 @@ set(files
__vector/vector_bool.h
__vector/vector_bool_formatter.h
__verbose_abort
+ __verbose_trap
algorithm
any
array
diff --git a/libcxx/include/__verbose_trap b/libcxx/include/__verbose_trap
new file mode 100644
index 0000000000000..13ea727738c3b
--- /dev/null
+++ b/libcxx/include/__verbose_trap
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___VERBOSE_TRAP
+#define _LIBCPP___VERBOSE_TRAP
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_builtin(__builtin_verbose_trap)
+// AppleClang shipped a slightly different version of __builtin_verbose_trap from the upstream
+// version before upstream Clang actually got the builtin.
+// TODO: Remove once AppleClang supports the two-arguments version of the builtin.
+# if defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1700
+# define _LIBCPP_VERBOSE_TRAP(message) __builtin_verbose_trap(message)
+# else
+# define _LIBCPP_VERBOSE_TRAP(message) __builtin_verbose_trap("libc++", message)
+# endif
+#else
+# define _LIBCPP_VERBOSE_TRAP(message) ((void)message, __builtin_trap())
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___VERBOSE_TRAP
diff --git a/libcxx/vendor/llvm/default_assertion_handler.in b/libcxx/vendor/llvm/default_assertion_handler.in
index 1d6b21fc6bb45..90b202a2dae57 100644
--- a/libcxx/vendor/llvm/default_assertion_handler.in
+++ b/libcxx/vendor/llvm/default_assertion_handler.in
@@ -15,6 +15,7 @@
# include <__cxx03/__verbose_abort>
#else
# include <__config>
+# include <__verbose_trap>
# include <__verbose_abort>
#endif
@@ -28,18 +29,7 @@
#else
-# if __has_builtin(__builtin_verbose_trap)
-// AppleClang shipped a slightly different version of __builtin_verbose_trap from the upstream
-// version before upstream Clang actually got the builtin.
-// TODO: Remove once AppleClang supports the two-arguments version of the builtin.
-# if defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1700
-# define _LIBCPP_ASSERTION_HANDLER(message) __builtin_verbose_trap(message)
-# else
-# define _LIBCPP_ASSERTION_HANDLER(message) __builtin_verbose_trap("libc++", message)
-# endif
-# else
-# define _LIBCPP_ASSERTION_HANDLER(message) ((void)message, __builtin_trap())
-# endif
+# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
>From 1fcfec368e34964811270b9a10ad969814e3a691 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Fri, 11 Jul 2025 10:29:10 -0700
Subject: [PATCH 02/14] [libc++][hardening] Introduce a dylib function to log
hardening errors.
Unlike `verbose_abort`, this function merely logs the error but does not
terminate execution. It is intended to make it possible to implement the
`observe` semantic for Hardening.
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__configuration/availability.h | 5 ++
libcxx/include/__log_hardening_failure | 45 +++++++++++++++++
libcxx/src/CMakeLists.txt | 1 +
libcxx/src/log_hardening_failure.cpp | 49 +++++++++++++++++++
5 files changed, 101 insertions(+)
create mode 100644 libcxx/include/__log_hardening_failure
create mode 100644 libcxx/src/log_hardening_failure.cpp
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index c8e6d28584623..2f8be540e73e2 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -535,6 +535,7 @@ set(files
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
+ __log_hardening_failure
__math/abs.h
__math/copysign.h
__math/error_functions.h
diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index ae58e36b508b4..cb72e927caa9c 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -304,6 +304,11 @@
#define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15
#define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE
+// This controls whether the library provides a function to log hardening failures without terminating the program (for
+// the `observe` assertion semantic).
+#define _LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21
+#define _LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE
+
// This controls the availability of the C++17 std::pmr library,
// which is implemented in large part in the built library.
//
diff --git a/libcxx/include/__log_hardening_failure b/libcxx/include/__log_hardening_failure
new file mode 100644
index 0000000000000..73cff0ac64155
--- /dev/null
+++ b/libcxx/include/__log_hardening_failure
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___LOG_HARDENING_FAILURE
+#define _LIBCPP___LOG_HARDENING_FAILURE
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// This function should never be called directly from the code -- it should only be called through the
+// `_LIBCPP_LOG_HARDENING_FAILURE` macro.
+_LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_OVERRIDABLE_FUNC_VIS void
+__libcpp_log_hardening_failure(const char* message) _NOEXCEPT;
+
+// _LIBCPP_LOG_HARDENING_FAILURE(message)
+//
+// This macro is used to log a hardening failure without terminating the program (as is the case if the `observe`
+// assertion semantic is used). Where possible, it logs in a way that indicates a fatal error (which might include
+// capturing the stack trace).
+#if !defined(_LIBCPP_LOG_HARDENING_FAILURE)
+
+# if !_LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE
+// The decltype is there to suppress -Wunused warnings in this configuration.
+void __use(const char*);
+# define _LIBCPP_LOG_HARDENING_FAILURE(message) (decltype(::std::__use(message))())
+# else
+# define _LIBCPP_LOG_HARDENING_FAILURE(message) ::std::__libcpp_log_hardening_failure(message)
+# endif
+
+#endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LOG_HARDENING_FAILURE
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 97fe57a5f24f8..926deb3a1c732 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -30,6 +30,7 @@ set(LIBCXX_SOURCES
include/ryu/ryu.h
include/to_chars_floating_point.h
include/from_chars_floating_point.h
+ log_hardening_failure.cpp
memory.cpp
memory_resource.cpp
new_handler.cpp
diff --git a/libcxx/src/log_hardening_failure.cpp b/libcxx/src/log_hardening_failure.cpp
new file mode 100644
index 0000000000000..7e408a6f010b4
--- /dev/null
+++ b/libcxx/src/log_hardening_failure.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <__log_hardening_failure>
+#include <cstdio>
+
+#ifdef __BIONIC__
+# include <syslog.h>
+extern "C" void android_set_abort_message(const char* msg);
+#endif // __BIONIC__
+
+#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
+# include <os/reason_private.h>
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_WEAK void __libcpp_log_hardening_failure(const char* message) noexcept {
+ // On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
+#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
+ os_fault_with_payload(
+ /*reason_namespace=*/OS_REASON_SECURITY,
+ /*reason_code=*/0,
+ /*payload=*/nullptr,
+ /*payload_size=*/0,
+ /*reason_string=*/message,
+ /*reason_flags=*/0);
+
+#elif defined(__BIONIC__)
+ // Show error in tombstone.
+ android_set_abort_message(message);
+
+ // Show error in logcat.
+ openlog("libc++", 0, 0);
+ syslog(LOG_CRIT, "%s", message);
+ closelog();
+
+#else
+ fprintf(stderr, "%s", message);
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
>From debdf1452cb4a3ba5258313f9b5c0fae146dd576 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Fri, 11 Jul 2025 10:58:57 -0700
Subject: [PATCH 03/14] [libc++][hardening] Introduce assertion semantics.
---
libcxx/include/__config | 30 +++++
libcxx/test/support/check_assertion.h | 120 ++++++++++++++++--
.../vendor/llvm/default_assertion_handler.in | 21 ++-
libcxxabi/src/CMakeLists.txt | 15 +--
libcxxabi/src/demangle/DemangleConfig.h | 5 +
libcxxabi/src/log_error_and_continue.cpp | 48 +++++++
libcxxabi/src/log_error_and_continue.h | 16 +++
7 files changed, 229 insertions(+), 26 deletions(-)
create mode 100644 libcxxabi/src/log_error_and_continue.cpp
create mode 100644 libcxxabi/src/log_error_and_continue.h
diff --git a/libcxx/include/__config b/libcxx/include/__config
index d940461c30234..2223d466c2a7f 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -147,6 +147,36 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \
_LIBCPP_HARDENING_MODE_DEBUG
# endif
+// Hardening assertion semantics mirror the evaluation semantics of P3100 Contracts:
+// - `ignore` does not evaluate the assertion;
+// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
+// - `quick-enforce` terminates the program as fast as possible (via trapping);
+// - `enforce` logs an error and then terminates the program.
+// Notes:
+// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
+// to make adopting hardening easier but should not be used outside of this scenario;
+// - P3471 "Standard Library Hardening" wording precludes using the Contracts `ignore` semantic for hardened
+// preconditions in the Library; allowing this semantic to be used is a libc++ vendor extension.
+// clang-format off
+# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1)
+# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2)
+# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3)
+# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4)
+// clang-format on
+
+// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics.
+// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use
+// `enforce` (i.e., log and abort).
+# ifndef _LIBCPP_ASSERTION_SEMANTIC
+
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+# else
+# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+# endif
+
+# endif // _LIBCPP_ASSERTION_SEMANTIC
+
// } HARDENING
# define _LIBCPP_TOSTRING2(x) #x
diff --git a/libcxx/test/support/check_assertion.h b/libcxx/test/support/check_assertion.h
index a279400d651b4..7f8102d82970d 100644
--- a/libcxx/test/support/check_assertion.h
+++ b/libcxx/test/support/check_assertion.h
@@ -50,9 +50,17 @@ MatchResult MatchAssertionMessage(const std::string& text, std::string_view expe
std::regex assertion_format(".*###\\n(.*):(\\d+): assertion (.*) failed: (.*)\\n###");
std::smatch match_result;
- bool has_match = std::regex_match(text, match_result, assertion_format);
- assert(has_match);
- assert(match_result.size() == 5);
+ // If a non-terminating assertion semantic is used, more than one assertion might be triggered before the process
+ // dies, so we cannot expect the entire target string to match.
+ bool has_match = std::regex_search(text, match_result, assertion_format);
+ if (!has_match || match_result.size() != 5) {
+ std::stringstream matching_error;
+ matching_error //
+ << "Failed to parse the assertion message.\n" //
+ << "Expected message: '" << expected_message.data() << "'\n" //
+ << "Stderr contents: '" << text.c_str() << "'\n";
+ return MatchResult(/*success=*/false, matching_error.str());
+ }
const std::string& file = match_result[1];
int line = std::stoi(match_result[2]);
@@ -85,13 +93,16 @@ Matcher MakeAnyMatcher() {
}
enum class DeathCause {
- // Valid causes
+ // Valid causes.
VerboseAbort = 1,
StdAbort,
StdTerminate,
Trap,
- // Invalid causes
+ // Causes that might be invalid or might stem from undefined behavior (relevant for non-terminating assertion
+ // semantics).
DidNotDie,
+ Segfault,
+ // Always invalid causes.
SetupFailure,
Unknown
};
@@ -108,6 +119,16 @@ bool IsValidCause(DeathCause cause) {
}
}
+bool IsTestSetupErrorCause(DeathCause cause) {
+ switch (cause) {
+ case DeathCause::SetupFailure:
+ case DeathCause::Unknown:
+ return true;
+ default:
+ return false;
+ }
+}
+
std::string ToString(DeathCause cause) {
switch (cause) {
case DeathCause::VerboseAbort:
@@ -120,10 +141,12 @@ std::string ToString(DeathCause cause) {
return "trap";
case DeathCause::DidNotDie:
return "<invalid cause (child did not die)>";
+ case DeathCause::Segfault:
+ return "<invalid cause (segmentation fault)>";
case DeathCause::SetupFailure:
- return "<invalid cause (child failed to set up test environment)>";
+ return "<test setup error (child failed to set up test environment)>";
case DeathCause::Unknown:
- return "<invalid cause (cause unknown)>";
+ return "<test setup error (test doesn't know how to interpret the death cause)>";
}
assert(false && "Unreachable");
@@ -225,9 +248,38 @@ class DeathTest {
return DeathTestResult(Outcome::Success, cause);
}
- void PrintFailureDetails(std::string_view failure_description, std::string_view stmt, DeathCause cause) const {
- std::fprintf(
- stderr, "Failure: EXPECT_DEATH( %s ) failed!\n(reason: %s)\n\n", stmt.data(), failure_description.data());
+ // When non-terminating assertion semantics are used, the program will invoke UB which might or might not crash the
+ // process; we make sure that the execution produces the expected error message but otherwise consider the test run
+ // successful whether the child process dies or not.
+ template <class Func>
+ DeathTestResult RunWithoutGuaranteedDeath(Func&& func, const Matcher& matcher) {
+ std::signal(SIGABRT, [](int) { StopChildProcess(DeathCause::StdAbort); });
+ std::set_terminate([] { StopChildProcess(DeathCause::StdTerminate); });
+
+ DeathCause cause = Run(func);
+
+ if (IsTestSetupErrorCause(cause)) {
+ return DeathTestResult(Outcome::InvalidCause, cause, ToString(cause));
+ }
+
+ MatchResult match_result = matcher(GetChildStdErr());
+ if (!match_result.first) {
+ auto failure_description = std::string("Child produced a different error message\n") + match_result.second;
+ return DeathTestResult(Outcome::UnexpectedErrorMessage, cause, failure_description);
+ }
+
+ return DeathTestResult(Outcome::Success, cause);
+ }
+
+ void PrintFailureDetails(std::string_view invocation,
+ std::string_view failure_description,
+ std::string_view stmt,
+ DeathCause cause) const {
+ std::fprintf(stderr,
+ "Failure: %s( %s ) failed!\n(reason: %s)\n\n",
+ invocation.data(),
+ stmt.data(),
+ failure_description.data());
if (cause != DeathCause::Unknown) {
std::fprintf(stderr, "child exit code: %d\n", GetChildExitCode());
@@ -311,10 +363,13 @@ class DeathTest {
if (WIFSIGNALED(status_value)) {
exit_code_ = WTERMSIG(status_value);
- // `__builtin_trap` generqtes `SIGILL` on x86 and `SIGTRAP` on ARM.
+ // `__builtin_trap` generates `SIGILL` on x86 and `SIGTRAP` on ARM.
if (exit_code_ == SIGILL || exit_code_ == SIGTRAP) {
return DeathCause::Trap;
}
+ if (exit_code_ == SIGSEGV) {
+ return DeathCause::Segfault;
+ }
}
return DeathCause::Unknown;
@@ -334,6 +389,12 @@ class DeathTest {
};
#ifdef _LIBCPP_VERSION
+void std::__libcpp_log_hardening_failure(const char* message) noexcept {
+ std::fprintf(stderr, "%s\n", Marker);
+ std::fprintf(stderr, "%s", message);
+ std::fprintf(stderr, "%s\n", Marker);
+}
+
void std::__libcpp_verbose_abort(char const* format, ...) noexcept {
va_list args;
va_start(args, format);
@@ -357,7 +418,7 @@ bool ExpectDeath(
DeathTest test_case;
DeathTestResult test_result = test_case.Run(expected_causes, func, matcher);
if (!test_result.success()) {
- test_case.PrintFailureDetails(test_result.failure_description(), stmt, test_result.cause());
+ test_case.PrintFailureDetails("EXPECT_DEATH", test_result.failure_description(), stmt, test_result.cause());
}
return test_result.success();
@@ -378,6 +439,22 @@ bool ExpectDeath(DeathCause expected_cause, const char* stmt, Func&& func) {
return ExpectDeath(std::array<DeathCause, 1>{expected_cause}, stmt, func, MakeAnyMatcher());
}
+template <class Func>
+bool ExpectLog(const char* stmt, Func&& func, const Matcher& matcher) {
+ DeathTest test_case;
+ DeathTestResult test_result = test_case.RunWithoutGuaranteedDeath(func, matcher);
+ if (!test_result.success()) {
+ test_case.PrintFailureDetails("EXPECT_LOG", test_result.failure_description(), stmt, test_result.cause());
+ }
+
+ return test_result.success();
+}
+
+template <class Func>
+bool ExpectLog(const char* stmt, Func&& func) {
+ return ExpectLog(stmt, func, MakeAnyMatcher());
+}
+
// clang-format off
/// Assert that the specified expression aborts with the expected cause and, optionally, error message.
@@ -392,13 +469,28 @@ bool ExpectDeath(DeathCause expected_cause, const char* stmt, Func&& func) {
#define EXPECT_STD_TERMINATE(...) \
assert( ExpectDeath(DeathCause::StdTerminate, #__VA_ARGS__, __VA_ARGS__) )
-#if defined(_LIBCPP_HARDENING_MODE) && _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+#if defined(_LIBCPP_ASSERTION_SEMANTIC)
+
+#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
assert(( ExpectDeath(DeathCause::VerboseAbort, #expr, [&]() { (void)(expr); }, MakeAssertionMessageMatcher(message)) ))
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
+ assert(( ExpectDeath(DeathCause::Trap, #expr, [&]() { (void)(expr); }) ))
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
+#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
+ assert(( ExpectLog(#expr, [&]() { (void)(expr); }, MakeAssertionMessageMatcher(message)) ))
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
+#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
+ assert(( ExpectLog(#expr, [&]() { (void)(expr); }) ))
+#else
+#error "_LIBCPP_ASSERTION_SEMANTIC is set to an invalid value"
+#endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+
#else
#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
assert(( ExpectDeath(DeathCause::Trap, #expr, [&]() { (void)(expr); }) ))
-#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+#endif // defined(_LIBCPP_ASSERTION_SEMANTIC)
// clang-format on
diff --git a/libcxx/vendor/llvm/default_assertion_handler.in b/libcxx/vendor/llvm/default_assertion_handler.in
index 90b202a2dae57..4ece031c03ece 100644
--- a/libcxx/vendor/llvm/default_assertion_handler.in
+++ b/libcxx/vendor/llvm/default_assertion_handler.in
@@ -15,22 +15,35 @@
# include <__cxx03/__verbose_abort>
#else
# include <__config>
-# include <__verbose_trap>
+# include <__log_hardening_failure>
# include <__verbose_abort>
+# include <__verbose_trap>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
-#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
+# define _LIBCPP_ASSERTION_HANDLER(message) ((void)0)
+
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
+# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_HARDENING_FAILURE(message)
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
+
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
#else
-# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
+# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
+_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
+_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
+_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
+_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
-#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+#endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
#endif // _LIBCPP___ASSERTION_HANDLER
diff --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt
index 0675577aed6a1..9a9a65ce3aaa1 100644
--- a/libcxxabi/src/CMakeLists.txt
+++ b/libcxxabi/src/CMakeLists.txt
@@ -16,6 +16,7 @@ set(LIBCXXABI_SOURCES
# Internal files
abort_message.cpp
fallback_malloc.cpp
+ log_error_and_continue.cpp
private_typeinfo.cpp
)
@@ -172,12 +173,11 @@ if (LIBCXXABI_USE_LLVM_UNWINDER)
target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared)
endif()
endif()
-target_link_libraries(cxxabi_shared_objects
- PUBLIC cxxabi-headers
- PRIVATE cxx-headers runtimes-libc-headers ${LIBCXXABI_LIBRARIES})
+target_link_libraries(cxxabi_shared_objects PRIVATE cxx-headers ${LIBCXXABI_LIBRARIES})
if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG)
target_link_libraries(cxxabi_shared_objects PRIVATE ${LIBCXXABI_BUILTINS_LIBRARY})
endif()
+target_link_libraries(cxxabi_shared_objects PUBLIC cxxabi-headers)
set_target_properties(cxxabi_shared_objects
PROPERTIES
CXX_EXTENSIONS OFF
@@ -216,7 +216,7 @@ if (ZOS)
endif ()
target_link_libraries(cxxabi_shared
- PUBLIC cxxabi_shared_objects runtimes-libc-shared
+ PUBLIC cxxabi_shared_objects
PRIVATE ${LIBCXXABI_LIBRARIES})
if (LIBCXXABI_ENABLE_SHARED)
@@ -275,9 +275,8 @@ if (LIBCXXABI_USE_LLVM_UNWINDER AND LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC
target_link_libraries(cxxabi_static_objects PUBLIC unwind_static_objects) # propagate usage requirements
target_sources(cxxabi_static_objects PUBLIC $<TARGET_OBJECTS:unwind_static_objects>)
endif()
-target_link_libraries(cxxabi_static_objects
- PUBLIC cxxabi-headers
- PRIVATE cxx-headers runtimes-libc-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
+target_link_libraries(cxxabi_static_objects PRIVATE cxx-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
+target_link_libraries(cxxabi_static_objects PUBLIC cxxabi-headers)
set_target_properties(cxxabi_static_objects
PROPERTIES
CXX_EXTENSIONS OFF
@@ -313,7 +312,7 @@ endif()
add_library(cxxabi_static STATIC)
if (LIBCXXABI_USE_LLVM_UNWINDER AND NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
- target_link_libraries(cxxabi_static PUBLIC unwind_static runtimes-libc-static)
+ target_link_libraries(cxxabi_static PUBLIC unwind_static)
endif()
set_target_properties(cxxabi_static
PROPERTIES
diff --git a/libcxxabi/src/demangle/DemangleConfig.h b/libcxxabi/src/demangle/DemangleConfig.h
index 06fd223f5553f..994d59507588f 100644
--- a/libcxxabi/src/demangle/DemangleConfig.h
+++ b/libcxxabi/src/demangle/DemangleConfig.h
@@ -19,6 +19,11 @@
#include "../abort_message.h"
#endif
+#ifndef _LIBCPP_LOG_HARDENING_FAILURE
+#define _LIBCPP_LOG_HARDENING_FAILURE(message) __log_error_and_continue(message)
+#include "../log_error_and_continue.h"
+#endif
+
#include <version>
#ifdef _MSC_VER
diff --git a/libcxxabi/src/log_error_and_continue.cpp b/libcxxabi/src/log_error_and_continue.cpp
new file mode 100644
index 0000000000000..51088cd11d914
--- /dev/null
+++ b/libcxxabi/src/log_error_and_continue.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "log_error_and_continue.h"
+
+#ifdef __BIONIC__
+# include <syslog.h>
+extern "C" void android_set_abort_message(const char* msg);
+#endif // __BIONIC__
+
+#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
+# include <os/reason_private.h>
+# define _LIBCXXABI_USE_OS_FAULT
+#endif
+
+void __log_error_and_continue(const char* message)
+{
+ // On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
+#if defined(_LIBCXXABI_USE_OS_FAULT)
+ os_fault_with_payload(
+ /*reason_namespace=*/OS_REASON_SECURITY,
+ /*reason_code=*/0,
+ /*payload=*/nullptr,
+ /*payload_size=*/0,
+ /*reason_string=*/message,
+ /*reason_flags=*/0);
+
+#elif defined(__BIONIC__)
+ // Show error in tombstone.
+ android_set_abort_message(message);
+
+ // Show error in logcat.
+ openlog("libc++", 0, 0);
+ syslog(LOG_CRIT, "%s", message);
+ closelog();
+
+#else
+ fprintf(stderr, "%s", message);
+#endif
+}
diff --git a/libcxxabi/src/log_error_and_continue.h b/libcxxabi/src/log_error_and_continue.h
new file mode 100644
index 0000000000000..e976c1de65d06
--- /dev/null
+++ b/libcxxabi/src/log_error_and_continue.h
@@ -0,0 +1,16 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 __LOG_ERROR_AND_CONTINUE_H_
+#define __LOG_ERROR_AND_CONTINUE_H_
+
+#include "cxxabi.h"
+
+extern "C" _LIBCXXABI_HIDDEN void __log_error_and_continue(const char* message);
+
+#endif // __LOG_ERROR_AND_CONTINUE_H_
>From 3ca83e671aa6b147cd855fc22d127d9b2fd16915 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 01:11:47 -0700
Subject: [PATCH 04/14] Address feedback
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__cxx03/__verbose_trap | 36 +++++++++++++++++++
libcxx/include/module.modulemap.in | 3 ++
.../vendor/llvm/default_assertion_handler.in | 3 +-
4 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 libcxx/include/__cxx03/__verbose_trap
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index f79edc9e32599..4f2a8dddad92c 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -1570,6 +1570,7 @@ set(files
__cxx03/__utility/unreachable.h
__cxx03/__variant/monostate.h
__cxx03/__verbose_abort
+ __cxx03/__verbose_trap
__cxx03/algorithm
__cxx03/array
__cxx03/atomic
diff --git a/libcxx/include/__cxx03/__verbose_trap b/libcxx/include/__cxx03/__verbose_trap
new file mode 100644
index 0000000000000..755124b97a5ac
--- /dev/null
+++ b/libcxx/include/__cxx03/__verbose_trap
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CXX03___VERBOSE_TRAP
+#define _LIBCPP___CXX03___VERBOSE_TRAP
+
+#include <__cxx03/__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_builtin(__builtin_verbose_trap)
+// AppleClang shipped a slightly different version of __builtin_verbose_trap from the upstream
+// version before upstream Clang actually got the builtin.
+// TODO: Remove once AppleClang supports the two-arguments version of the builtin.
+# if defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1700
+# define _LIBCPP_VERBOSE_TRAP(message) __builtin_verbose_trap(message)
+# else
+# define _LIBCPP_VERBOSE_TRAP(message) __builtin_verbose_trap("libc++", message)
+# endif
+#else
+# define _LIBCPP_VERBOSE_TRAP(message) ((void)message, __builtin_trap())
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CXX03___VERBOSE_TRAP
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 45b9c72a05b82..61ba1c381b2b3 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2356,6 +2356,9 @@ module std [system] {
module verbose_abort {
header "__verbose_abort"
}
+ module verbose_trap {
+ header "__verbose_trap"
+ }
module internal_assert {
header "__assert"
export *
diff --git a/libcxx/vendor/llvm/default_assertion_handler.in b/libcxx/vendor/llvm/default_assertion_handler.in
index 90b202a2dae57..f115658f9f3c6 100644
--- a/libcxx/vendor/llvm/default_assertion_handler.in
+++ b/libcxx/vendor/llvm/default_assertion_handler.in
@@ -13,10 +13,11 @@
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
# include <__cxx03/__config>
# include <__cxx03/__verbose_abort>
+# include <__cxx03/__verbose_trap>
#else
# include <__config>
-# include <__verbose_trap>
# include <__verbose_abort>
+# include <__verbose_trap>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
>From ef34aded6cfa935fe9d904bb8d4f79bfb705137a Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 01:58:15 -0700
Subject: [PATCH 05/14] Address feedback
---
libcxx/include/CMakeLists.txt | 2 +-
libcxx/include/__configuration/availability.h | 8 +--
libcxx/include/__log_error | 50 +++++++++++++++++++
libcxx/include/__log_hardening_failure | 45 -----------------
libcxx/include/module.modulemap.in | 3 ++
libcxx/src/CMakeLists.txt | 2 +-
...og_hardening_failure.cpp => log_error.cpp} | 16 +++++-
7 files changed, 73 insertions(+), 53 deletions(-)
create mode 100644 libcxx/include/__log_error
delete mode 100644 libcxx/include/__log_hardening_failure
rename libcxx/src/{log_hardening_failure.cpp => log_error.cpp} (81%)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 2f8be540e73e2..ceaf45e9e8ae6 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -535,7 +535,7 @@ set(files
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
- __log_hardening_failure
+ __log_error
__math/abs.h
__math/copysign.h
__math/error_functions.h
diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index cb72e927caa9c..5de0b98ba22a9 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -304,10 +304,10 @@
#define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15
#define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE
-// This controls whether the library provides a function to log hardening failures without terminating the program (for
-// the `observe` assertion semantic).
-#define _LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21
-#define _LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE
+// This controls whether the library provides a function to log errors without terminating the program (used in
+// particular by the `observe` assertion semantic).
+#define _LIBCPP_AVAILABILITY_HAS_LOG_ERROR _LIBCPP_INTRODUCED_IN_LLVM_21
+#define _LIBCPP_AVAILABILITY_LOG_ERROR _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE
// This controls the availability of the C++17 std::pmr library,
// which is implemented in large part in the built library.
diff --git a/libcxx/include/__log_error b/libcxx/include/__log_error
new file mode 100644
index 0000000000000..9f308898247c4
--- /dev/null
+++ b/libcxx/include/__log_error
@@ -0,0 +1,50 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___LOG_ERROR
+#define _LIBCPP___LOG_ERROR
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LogErrorReason {
+ // Where possible, it logs in a way that indicates a fatal error (which might include capturing the stack trace).
+ _HardeningFailure
+};
+
+// This function should never be called directly from the code -- it should only be called through the
+// `_LIBCPP_LOG_ERROR` macro.
+_LIBCPP_AVAILABILITY_LOG_ERROR _LIBCPP_EXPORTED_FROM_ABI void
+__log_error(_LogErrorReason __reason, const char* __message) _NOEXCEPT;
+
+// _LIBCPP_LOG_ERROR(message)
+//
+// This macro is used to log an error without terminating the program (as is the case for hardening failures if the
+// `observe` assertion semantic is used, for example).
+
+#if !defined(_LIBCPP_LOG_ERROR)
+
+# if !_LIBCPP_AVAILABILITY_HAS_LOG_ERROR
+// The decltype is there to suppress -Wunused warnings in this configuration.
+void __use(const char*);
+# define _LIBCPP_LOG_ERROR(__message) (decltype(::std::__use(__message))())
+# else
+# define _LIBCPP_LOG_ERROR(__reason, __message) ::std::__log_error(__reason, __message)
+# endif
+
+#endif // !defined(_LIBCPP_LOG_ERROR)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LOG_ERROR
diff --git a/libcxx/include/__log_hardening_failure b/libcxx/include/__log_hardening_failure
deleted file mode 100644
index 73cff0ac64155..0000000000000
--- a/libcxx/include/__log_hardening_failure
+++ /dev/null
@@ -1,45 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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___LOG_HARDENING_FAILURE
-#define _LIBCPP___LOG_HARDENING_FAILURE
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// This function should never be called directly from the code -- it should only be called through the
-// `_LIBCPP_LOG_HARDENING_FAILURE` macro.
-_LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_OVERRIDABLE_FUNC_VIS void
-__libcpp_log_hardening_failure(const char* message) _NOEXCEPT;
-
-// _LIBCPP_LOG_HARDENING_FAILURE(message)
-//
-// This macro is used to log a hardening failure without terminating the program (as is the case if the `observe`
-// assertion semantic is used). Where possible, it logs in a way that indicates a fatal error (which might include
-// capturing the stack trace).
-#if !defined(_LIBCPP_LOG_HARDENING_FAILURE)
-
-# if !_LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE
-// The decltype is there to suppress -Wunused warnings in this configuration.
-void __use(const char*);
-# define _LIBCPP_LOG_HARDENING_FAILURE(message) (decltype(::std::__use(message))())
-# else
-# define _LIBCPP_LOG_HARDENING_FAILURE(message) ::std::__libcpp_log_hardening_failure(message)
-# endif
-
-#endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE)
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___LOG_HARDENING_FAILURE
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 45b9c72a05b82..763d32296a03d 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2353,6 +2353,9 @@ module std [system] {
header "__std_mbstate_t.h"
export *
}
+ module log_error {
+ header "__log_error"
+ }
module verbose_abort {
header "__verbose_abort"
}
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 926deb3a1c732..0e83b2728aa5a 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -30,7 +30,7 @@ set(LIBCXX_SOURCES
include/ryu/ryu.h
include/to_chars_floating_point.h
include/from_chars_floating_point.h
- log_hardening_failure.cpp
+ log_error.cpp
memory.cpp
memory_resource.cpp
new_handler.cpp
diff --git a/libcxx/src/log_hardening_failure.cpp b/libcxx/src/log_error.cpp
similarity index 81%
rename from libcxx/src/log_hardening_failure.cpp
rename to libcxx/src/log_error.cpp
index 7e408a6f010b4..01ddaf65bf618 100644
--- a/libcxx/src/log_hardening_failure.cpp
+++ b/libcxx/src/log_error.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include <__config>
-#include <__log_hardening_failure>
+#include <__log_error>
#include <cstdio>
#ifdef __BIONIC__
@@ -21,7 +21,9 @@ extern "C" void android_set_abort_message(const char* msg);
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_WEAK void __libcpp_log_hardening_failure(const char* message) noexcept {
+namespace {
+
+void log_fatal_error(const char* message) noexcept {
// On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
os_fault_with_payload(
@@ -46,4 +48,14 @@ _LIBCPP_WEAK void __libcpp_log_hardening_failure(const char* message) noexcept {
#endif
}
+} // namespace
+
+void __log_error(_LogErrorReason reason, const char* message) noexcept {
+ switch (reason) {
+ case _LogErrorReason::_HardeningFailure:
+ default:
+ log_fatal_error(message);
+ }
+}
+
_LIBCPP_END_NAMESPACE_STD
>From 01eb85de6072d3b188cf357573826f663ebfa51d Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 15:01:05 -0700
Subject: [PATCH 06/14] Update the ABI list plus minor tweaks.
---
...le-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 5 +++--
libcxx/src/CMakeLists.txt | 2 +-
libcxx/src/log_error.cpp | 4 ++--
libcxx/utils/libcxx/test/features.py | 8 ++++++++
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 162757c7e37ec..bc6bdca5b8a2d 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -534,6 +534,7 @@
{'is_defined': True, 'name': '__ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -944,6 +945,7 @@
{'is_defined': True, 'name': '__ZNSt3__110to_wstringEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110to_wstringEy', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__111__call_onceERVmPvPFvS2_E', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__111__log_errorENS_15_LogErrorReasonEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__111__money_getIcE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_SF_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__111__money_getIwE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERwS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERNS9_IwNSA_IwEENSC_IwEEEESJ_SJ_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__111__money_putIcE13__gather_infoEbbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_Ri', 'type': 'FUNC'}
@@ -1125,6 +1127,7 @@
{'is_defined': True, 'name': '__ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -1305,7 +1308,6 @@
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1508,7 +1510,6 @@
{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 0e83b2728aa5a..fe8e57690a880 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -30,8 +30,8 @@ set(LIBCXX_SOURCES
include/ryu/ryu.h
include/to_chars_floating_point.h
include/from_chars_floating_point.h
- log_error.cpp
memory.cpp
+ log_error.cpp
memory_resource.cpp
new_handler.cpp
new_helpers.cpp
diff --git a/libcxx/src/log_error.cpp b/libcxx/src/log_error.cpp
index 01ddaf65bf618..53cf3c7aa7ac2 100644
--- a/libcxx/src/log_error.cpp
+++ b/libcxx/src/log_error.cpp
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace {
-void log_fatal_error(const char* message) noexcept {
+void log_security_failure(const char* message) noexcept {
// On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
os_fault_with_payload(
@@ -54,7 +54,7 @@ void __log_error(_LogErrorReason reason, const char* message) noexcept {
switch (reason) {
case _LogErrorReason::_HardeningFailure:
default:
- log_fatal_error(message);
+ log_security_failure(message);
}
}
diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 0cb81546665d4..8433ea178080b 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -894,6 +894,14 @@ def check_gdb(cfg):
cfg.available_features,
),
),
+ # Tests that require __log_error support in the built library
+ Feature(
+ name="availability-log_error-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-21)",
+ cfg.available_features,
+ ),
+ ),
# Tests that require std::pmr support in the built library
Feature(
name="availability-pmr-missing",
>From 189cdc1809855f6d02ad68982a017facdd787634 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 15:58:27 -0700
Subject: [PATCH 07/14] Address feedback.
---
libcxx/include/__config | 12 +++--
.../vendor/llvm/default_assertion_handler.in | 4 +-
libcxxabi/src/CMakeLists.txt | 1 -
libcxxabi/src/demangle/DemangleConfig.h | 8 ++--
libcxxabi/src/log_error_and_continue.cpp | 48 -------------------
libcxxabi/src/log_error_and_continue.h | 16 -------
6 files changed, 15 insertions(+), 74 deletions(-)
delete mode 100644 libcxxabi/src/log_error_and_continue.cpp
delete mode 100644 libcxxabi/src/log_error_and_continue.h
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 2223d466c2a7f..ef0c8b48b658b 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -147,16 +147,20 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \
_LIBCPP_HARDENING_MODE_DEBUG
# endif
-// Hardening assertion semantics mirror the evaluation semantics of P3100 Contracts:
-// - `ignore` does not evaluate the assertion;
+// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
+// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
+// `ignore` semantic which wouldn't evaluate the assertion at all);
// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
// - `quick-enforce` terminates the program as fast as possible (via trapping);
// - `enforce` logs an error and then terminates the program.
+//
// Notes:
// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
// to make adopting hardening easier but should not be used outside of this scenario;
-// - P3471 "Standard Library Hardening" wording precludes using the Contracts `ignore` semantic for hardened
-// preconditions in the Library; allowing this semantic to be used is a libc++ vendor extension.
+// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
+// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
+// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
+// implementation, unlike the other semantics above.
// clang-format off
# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1)
# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2)
diff --git a/libcxx/vendor/llvm/default_assertion_handler.in b/libcxx/vendor/llvm/default_assertion_handler.in
index 3ec9a94790712..d1ddedf1bb31b 100644
--- a/libcxx/vendor/llvm/default_assertion_handler.in
+++ b/libcxx/vendor/llvm/default_assertion_handler.in
@@ -16,7 +16,7 @@
# include <__cxx03/__verbose_trap>
#else
# include <__config>
-# include <__log_hardening_failure>
+# include <__log_error>
# include <__verbose_abort>
# include <__verbose_trap>
#endif
@@ -29,7 +29,7 @@
# define _LIBCPP_ASSERTION_HANDLER(message) ((void)0)
#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
-# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_HARDENING_FAILURE(message)
+# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_ERROR(_LogErrorReason::_HardeningFailure, message)
#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
diff --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt
index 9a9a65ce3aaa1..0a6fc892a4f69 100644
--- a/libcxxabi/src/CMakeLists.txt
+++ b/libcxxabi/src/CMakeLists.txt
@@ -16,7 +16,6 @@ set(LIBCXXABI_SOURCES
# Internal files
abort_message.cpp
fallback_malloc.cpp
- log_error_and_continue.cpp
private_typeinfo.cpp
)
diff --git a/libcxxabi/src/demangle/DemangleConfig.h b/libcxxabi/src/demangle/DemangleConfig.h
index 994d59507588f..f1f161a54afbd 100644
--- a/libcxxabi/src/demangle/DemangleConfig.h
+++ b/libcxxabi/src/demangle/DemangleConfig.h
@@ -19,9 +19,11 @@
#include "../abort_message.h"
#endif
-#ifndef _LIBCPP_LOG_HARDENING_FAILURE
-#define _LIBCPP_LOG_HARDENING_FAILURE(message) __log_error_and_continue(message)
-#include "../log_error_and_continue.h"
+#ifndef _LIBCPP_LOG_ERROR
+// Libc++abi does not have any functionality to log and continue, so we drop error messages when we build the demangler
+// with `observe` assertion semantic. Once the layering with libc++ is improved, this could use the libc++ functionality
+// to log hardening failures.
+#define _LIBCPP_LOG_ERROR(reason, message) ((void)0)
#endif
#include <version>
diff --git a/libcxxabi/src/log_error_and_continue.cpp b/libcxxabi/src/log_error_and_continue.cpp
deleted file mode 100644
index 51088cd11d914..0000000000000
--- a/libcxxabi/src/log_error_and_continue.cpp
+++ /dev/null
@@ -1,48 +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
-//
-//===----------------------------------------------------------------------===//
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include "log_error_and_continue.h"
-
-#ifdef __BIONIC__
-# include <syslog.h>
-extern "C" void android_set_abort_message(const char* msg);
-#endif // __BIONIC__
-
-#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
-# include <os/reason_private.h>
-# define _LIBCXXABI_USE_OS_FAULT
-#endif
-
-void __log_error_and_continue(const char* message)
-{
- // On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
-#if defined(_LIBCXXABI_USE_OS_FAULT)
- os_fault_with_payload(
- /*reason_namespace=*/OS_REASON_SECURITY,
- /*reason_code=*/0,
- /*payload=*/nullptr,
- /*payload_size=*/0,
- /*reason_string=*/message,
- /*reason_flags=*/0);
-
-#elif defined(__BIONIC__)
- // Show error in tombstone.
- android_set_abort_message(message);
-
- // Show error in logcat.
- openlog("libc++", 0, 0);
- syslog(LOG_CRIT, "%s", message);
- closelog();
-
-#else
- fprintf(stderr, "%s", message);
-#endif
-}
diff --git a/libcxxabi/src/log_error_and_continue.h b/libcxxabi/src/log_error_and_continue.h
deleted file mode 100644
index e976c1de65d06..0000000000000
--- a/libcxxabi/src/log_error_and_continue.h
+++ /dev/null
@@ -1,16 +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 __LOG_ERROR_AND_CONTINUE_H_
-#define __LOG_ERROR_AND_CONTINUE_H_
-
-#include "cxxabi.h"
-
-extern "C" _LIBCXXABI_HIDDEN void __log_error_and_continue(const char* message);
-
-#endif // __LOG_ERROR_AND_CONTINUE_H_
>From 94ef9a34532637011ec831c321447b3566764fa8 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 18:38:03 -0700
Subject: [PATCH 08/14] Test improvements
---
libcxx/src/log_error.cpp | 6 ++---
.../extents/assert.ctor_from_array.pass.cpp | 21 +++++++++++-----
.../assert.ctor_from_integral.pass.cpp | 6 ++---
.../layout_left/assert.conversion.pass.cpp | 4 +--
.../layout_left/assert.ctor.extents.pass.cpp | 5 +++-
.../assert.ctor.layout_right.pass.cpp | 4 +--
.../layout_right/assert.conversion.pass.cpp | 6 ++---
.../layout_right/assert.ctor.extents.pass.cpp | 3 ++-
.../assert.ctor.layout_left.pass.cpp | 4 +--
.../layout_stride/assert.conversion.pass.cpp | 18 +++++++------
...ert.ctor.extents_array.non_unique.pass.cpp | 4 +--
.../assert.ctor.extents_array.pass.cpp | 8 +++---
...sert.ctor.extents_span.non_unique.pass.cpp | 4 +--
.../thread/thread.latch/assert.ctor.pass.cpp | 9 ++++---
.../thread.semaphore/assert.ctor.pass.cpp | 2 +-
.../assert.ctor.pass.cpp | 2 ++
.../assert.ctor.pass.cpp | 2 ++
.../assert.to_local.pass.cpp | 1 +
.../time.zone.members/assert.to_sys.pass.cpp | 2 ++
.../assert.to_sys_choose.pass.cpp | 2 ++
libcxx/test/support/check_assertion.h | 25 +++++++++++--------
.../vendor/llvm/default_assertion_handler.in | 2 +-
22 files changed, 84 insertions(+), 56 deletions(-)
diff --git a/libcxx/src/log_error.cpp b/libcxx/src/log_error.cpp
index 53cf3c7aa7ac2..4e695ff380e8e 100644
--- a/libcxx/src/log_error.cpp
+++ b/libcxx/src/log_error.cpp
@@ -24,6 +24,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace {
void log_security_failure(const char* message) noexcept {
+ // Always log the message to `stderr` in case the platform-specific system calls fail.
+ fprintf(stderr, "%s", message);
+
// On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
os_fault_with_payload(
@@ -42,9 +45,6 @@ void log_security_failure(const char* message) noexcept {
openlog("libc++", 0, 0);
syslog(LOG_CRIT, "%s", message);
closelog();
-
-#else
- fprintf(stderr, "%s", message);
#endif
}
diff --git a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
index 90cb0c84a063b..6849b6a5f2e6c 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
@@ -43,18 +43,27 @@ int main(int, char**) {
}
// mismatch of static extent
{
- TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<int, D, 5> e1(std::array{1000, 3}); }()),
- "extents construction: mismatch of provided arguments with static extents.");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ [[maybe_unused]] std::extents<int, D, 5> e1(std::array{1000, 3});
+ }()),
+ "extents construction: mismatch of provided arguments with static extents.");
}
// value out of range
{
- TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(std::array{1000, 5}); }()),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ [[maybe_unused]] std::extents<signed char, D, 5> e1(std::array{1000, 5});
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
// negative value
{
- TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(std::array{-1, 5}); }()),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ [[maybe_unused]] std::extents<signed char, D, 5> e1(std::array{-1, 5});
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
return 0;
}
diff --git a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
index 37e79aabf8532..17bab03b922e6 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
@@ -45,17 +45,17 @@ int main(int, char**) {
}
// mismatch of static extent
{
- TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<int, D, 5> e1(1000, 3); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents<int, D, 5> e1(1000, 3); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// value out of range
{
- TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(1000, 5); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents<signed char, D, 5> e1(1000, 5); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
// negative value
{
- TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(-1, 5); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents<signed char, D, 5> e1(-1, 5); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
return 0;
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
index 7b6616f19d724..c67529671fcf7 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
@@ -44,7 +44,7 @@ int main(int, char**) {
{
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_left::mapping<std::extents<signed char, D>> m(
+ [[maybe_unused]] std::layout_left::mapping<std::extents<signed char, D>> m(
std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
@@ -55,7 +55,7 @@ int main(int, char**) {
[[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
// but the product is not, so we can't use it for layout_left
TEST_LIBCPP_ASSERT_FAILURE(
- ([=] { std::layout_left::mapping<std::extents<signed char, D, 5>> m(arg); }()),
+ ([=] { [[maybe_unused]] std::layout_left::mapping<std::extents<signed char, D, 5>> m(arg); }()),
"layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
return 0;
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
index 7c96f8ec9353f..45f07f1ed5c06 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
@@ -31,7 +31,10 @@ int main(int, char**) {
{
// the extents are representable but the product is not, so we can't use it for layout_left
TEST_LIBCPP_ASSERT_FAILURE(
- ([=] { std::layout_left::mapping<std::extents<signed char, D, 5>> m(std::extents<signed char, D, 5>(100)); }()),
+ ([=] {
+ [[maybe_unused]] std::layout_left::mapping<std::extents<signed char, D, 5>> m(
+ std::extents<signed char, D, 5>(100));
+ }()),
"layout_left::mapping extents ctor: product of extents must be representable as index_type.");
}
return 0;
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
index e578bac2103b0..04a6c59d265e1 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
@@ -39,14 +39,14 @@ int main(int, char**) {
}
// mismatch of static extent
{
- TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<int, 3>> m(arg); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_left::mapping<std::extents<int, 3>> m(arg); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// non-representability of extents itself
{
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_left::mapping<std::extents<signed char, D>> m(
+ [[maybe_unused]] std::layout_left::mapping<std::extents<signed char, D>> m(
std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
index df16edb925407..81fc8b5d65e62 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
@@ -37,14 +37,14 @@ int main(int, char**) {
}
// mismatch of static extent
{
- TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<int, D, 3>> m(arg); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_right::mapping<std::extents<int, D, 3>> m(arg); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// non-representability of extents itself
{
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_right::mapping<std::extents<signed char, D>> m(
+ [[maybe_unused]] std::layout_right::mapping<std::extents<signed char, D>> m(
std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
@@ -55,7 +55,7 @@ int main(int, char**) {
[[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
// but the product is not, so we can't use it for layout_right
TEST_LIBCPP_ASSERT_FAILURE(
- ([=] { std::layout_right::mapping<std::extents<signed char, D, 5>> m(arg); }()),
+ ([=] { [[maybe_unused]] std::layout_right::mapping<std::extents<signed char, D, 5>> m(arg); }()),
"layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
return 0;
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
index 52095691f6d24..33b71fdfd052d 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
@@ -32,7 +32,8 @@ int main(int, char**) {
// the extents are representable but the product is not, so we can't use it for layout_right
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_right::mapping<std::extents<signed char, D, 5>> m(std::extents<signed char, D, 5>(100));
+ [[maybe_unused]] std::layout_right::mapping<std::extents<signed char, D, 5>> m(
+ std::extents<signed char, D, 5>(100));
}()),
"layout_right::mapping extents ctor: product of extents must be representable as index_type.");
}
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
index 1757ddb286b9c..32972771f242d 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
@@ -39,14 +39,14 @@ int main(int, char**) {
}
// mismatch of static extent
{
- TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<int, 3>> m(arg); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_right::mapping<std::extents<int, 3>> m(arg); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// non-representability of extents itself
{
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_right::mapping<std::extents<signed char, D>> m(
+ [[maybe_unused]] std::layout_right::mapping<std::extents<signed char, D>> m(
std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp
index 7deb1215de0de..7b1739e0d1031 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp
@@ -58,14 +58,14 @@ int main(int, char**) {
{
std::extents<int, D, D> arg_exts{100, 5};
std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{1, 100});
- TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<int, D, 3>> m(arg); }()),
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_stride::mapping<std::extents<int, D, 3>> m(arg); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// non-representability of extents itself
{
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<signed char, D>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<signed char, D>> m(
std::layout_stride::mapping<std::extents<int, D>>(std::extents<int, D>(500), std::array<int, 1>{1}));
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
@@ -73,8 +73,9 @@ int main(int, char**) {
// all strides must be larger than zero
{
always_convertible_layout::mapping<std::dextents<int, 2>> offset_map(std::dextents<int, 2>{10, 10}, 100, -1);
- TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
- "layout_stride::mapping converting ctor: all strides must be greater than 0");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { [[maybe_unused]] std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
+ "layout_stride::mapping converting ctor: all strides must be greater than 0");
}
// required_span_size not representable, while individual extents are
{
@@ -84,7 +85,7 @@ int main(int, char**) {
[[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
// but the product is not, so we can't use it for layout_stride
TEST_LIBCPP_ASSERT_FAILURE(
- ([=] { std::layout_stride::mapping<std::extents<signed char, D, 5>> m(arg); }()),
+ ([=] { [[maybe_unused]] std::layout_stride::mapping<std::extents<signed char, D, 5>> m(arg); }()),
"layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
// required_span_size not representable, while individual extents are, edge case
@@ -98,14 +99,15 @@ int main(int, char**) {
[[maybe_unused]] std::extents<signed char, D, 10> e(arg_exts);
// but the product is not, so we can't use it for layout_stride
TEST_LIBCPP_ASSERT_FAILURE(
- ([=] { std::layout_stride::mapping<std::extents<signed char, D, 10>> m(arg); }()),
+ ([=] { [[maybe_unused]] std::layout_stride::mapping<std::extents<signed char, D, 10>> m(arg); }()),
"layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
// base offset must be 0 (i.e. mapping(0,...,0)==0) for a strided layout with positive strides
{
always_convertible_layout::mapping<std::dextents<int, 2>> offset_map(std::dextents<int, 2>{10, 10}, 3);
- TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
- "layout_stride::mapping converting ctor: base offset of mapping must be zero.");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { [[maybe_unused]] std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
+ "layout_stride::mapping converting ctor: base offset of mapping must be zero.");
}
return 0;
}
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp
index 97a6d56e4f839..a6120f8bf9c4b 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp
@@ -42,7 +42,7 @@ int main(int, char**) {
{
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<unsigned, D, 5, 7>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 7>> m(
std::extents<unsigned, D, 5, 7>(20), std::array<unsigned, 3>{4, 1, 200});
}()),
"layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
@@ -58,7 +58,7 @@ int main(int, char**) {
// will fail because neither of the equal strides is associated with an extent of 1
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m3(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m3(
std::extents<unsigned, D, 5, 2>(2), std::array<unsigned, 3>{5, 1, 5});
}()),
"layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp
index 860849ded2de2..9c52dd411b7c5 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp
@@ -42,7 +42,7 @@ int main(int, char**) {
// the extents are representable but the product with strides is not, so we can't use it for layout_stride
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<signed char, D, 5>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<signed char, D, 5>> m(
std::extents<signed char, D, 5>(20), std::array<int, 2>{20, 1});
}()),
"layout_stride::mapping ctor: required span size is not representable as index_type.");
@@ -51,7 +51,7 @@ int main(int, char**) {
static_assert(static_cast<unsigned char>(257u) == 1);
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<unsigned char, D, 5>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned char, D, 5>> m(
std::extents<unsigned char, D, 5>(20), std::array<unsigned, 2>{257, 1});
}()),
"layout_stride::mapping ctor: required span size is not representable as index_type.");
@@ -59,14 +59,14 @@ int main(int, char**) {
// negative strides are not allowed, check with unsigned index_type so we make sure we catch that
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
std::extents<unsigned, D, 5>(20), std::array<int, 2>{20, -1});
}()),
"layout_stride::mapping ctor: all strides must be greater than 0");
// zero strides are not allowed, check with unsigned index_type so we make sure we catch that
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
std::extents<unsigned, D, 5>(20), std::array<unsigned, 2>{20, 0});
}()),
"layout_stride::mapping ctor: all strides must be greater than 0");
diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp
index fd0701e9ee3a7..4752d3946aece 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp
@@ -43,7 +43,7 @@ int main(int, char**) {
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
std::array<unsigned, 3> strides{4, 1, 200};
- std::layout_stride::mapping<std::extents<unsigned, D, 5, 7>> m(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 7>> m(
std::extents<unsigned, D, 5, 7>(20), std::span(strides));
}()),
"layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
@@ -61,7 +61,7 @@ int main(int, char**) {
// will fail because neither of the equal strides is associated with an extent of 1
TEST_LIBCPP_ASSERT_FAILURE(
([=] {
- std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m3(
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m3(
std::extents<unsigned, D, 5, 2>(2), std::span(strides));
}()),
"layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
diff --git a/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp
index 5f1ea19d82a50..01fb907c3fbd4 100644
--- a/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp
+++ b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp
@@ -24,11 +24,12 @@
#include "check_assertion.h"
-int main(int, char **) {
+int main(int, char**) {
{
- TEST_LIBCPP_ASSERT_FAILURE([]{ std::latch l(-1); }(),
- "latch::latch(ptrdiff_t): latch cannot be "
- "initialized with a negative value");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ [] { [[maybe_unused]] std::latch l(-1); }(),
+ "latch::latch(ptrdiff_t): latch cannot be "
+ "initialized with a negative value");
}
// We can't check the precondition for max() because there's no value
diff --git a/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp
index 1e33add779496..c490948d36abe 100644
--- a/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp
+++ b/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp
@@ -26,7 +26,7 @@
int main(int, char**) {
{
TEST_LIBCPP_ASSERT_FAILURE(
- [] { std::counting_semaphore<> s(-1); }(),
+ [] { [[maybe_unused]] std::counting_semaphore<> s(-1); }(),
"counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be "
"initialized with a negative value");
}
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
index 73e6bf2846f0e..ee2370f5bce25 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
index fdd9f79958f98..5d896c34e4ccd 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
index d9ca1c80751cc..eb0ae4cf4b187 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
index 3a2ff00088676..57b7f8d0f30a0 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
index 65429345ae794..85ce6019fcd55 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/support/check_assertion.h b/libcxx/test/support/check_assertion.h
index 7f8102d82970d..d77c0bdb3615e 100644
--- a/libcxx/test/support/check_assertion.h
+++ b/libcxx/test/support/check_assertion.h
@@ -44,10 +44,18 @@ static constexpr const char* Marker = "###";
using MatchResult = std::pair<bool, std::string>;
using Matcher = std::function<MatchResult(const std::string& /*text*/)>;
-MatchResult MatchAssertionMessage(const std::string& text, std::string_view expected_message) {
+// Using the marker makes matching more precise, but we cannot output the marker when the `observe` semantic is used
+// (because it doesn't allow customizing the logging function). If the marker is not available, fall back to using less
+// precise matching by just the error message.
+MatchResult MatchAssertionMessage(const std::string& text, std::string_view expected_message, bool use_marker) {
// Extract information from the error message. This has to stay synchronized with how we format assertions in the
// library.
- std::regex assertion_format(".*###\\n(.*):(\\d+): assertion (.*) failed: (.*)\\n###");
+ std::string assertion_format_string = [&] {
+ if (use_marker)
+ return (".*###\\n(.*):(\\d+): assertion (.*) failed: (.*)\\n###");
+ return ("(.*):(\\d+): assertion (.*) failed: (.*)\\n");
+ }();
+ std::regex assertion_format(assertion_format_string);
std::smatch match_result;
// If a non-terminating assertion semantic is used, more than one assertion might be triggered before the process
@@ -57,6 +65,7 @@ MatchResult MatchAssertionMessage(const std::string& text, std::string_view expe
std::stringstream matching_error;
matching_error //
<< "Failed to parse the assertion message.\n" //
+ << "Using marker: " << use_marker << "\n" //
<< "Expected message: '" << expected_message.data() << "'\n" //
<< "Stderr contents: '" << text.c_str() << "'\n";
return MatchResult(/*success=*/false, matching_error.str());
@@ -80,9 +89,9 @@ MatchResult MatchAssertionMessage(const std::string& text, std::string_view expe
return MatchResult(/*success=*/true, /*maybe_error=*/"");
}
-Matcher MakeAssertionMessageMatcher(std::string_view assertion_message) {
+Matcher MakeAssertionMessageMatcher(std::string_view assertion_message, bool use_marker = true) {
return [=](const std::string& text) { //
- return MatchAssertionMessage(text, assertion_message);
+ return MatchAssertionMessage(text, assertion_message, use_marker);
};
}
@@ -389,12 +398,6 @@ class DeathTest {
};
#ifdef _LIBCPP_VERSION
-void std::__libcpp_log_hardening_failure(const char* message) noexcept {
- std::fprintf(stderr, "%s\n", Marker);
- std::fprintf(stderr, "%s", message);
- std::fprintf(stderr, "%s\n", Marker);
-}
-
void std::__libcpp_verbose_abort(char const* format, ...) noexcept {
va_list args;
va_start(args, format);
@@ -479,7 +482,7 @@ bool ExpectLog(const char* stmt, Func&& func) {
assert(( ExpectDeath(DeathCause::Trap, #expr, [&]() { (void)(expr); }) ))
#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
- assert(( ExpectLog(#expr, [&]() { (void)(expr); }, MakeAssertionMessageMatcher(message)) ))
+ assert(( ExpectLog(#expr, [&]() { (void)(expr); }, MakeAssertionMessageMatcher(message, /*use_marker=*/false)) ))
#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \
assert(( ExpectLog(#expr, [&]() { (void)(expr); }) ))
diff --git a/libcxx/vendor/llvm/default_assertion_handler.in b/libcxx/vendor/llvm/default_assertion_handler.in
index d1ddedf1bb31b..e113a1b82cdd2 100644
--- a/libcxx/vendor/llvm/default_assertion_handler.in
+++ b/libcxx/vendor/llvm/default_assertion_handler.in
@@ -29,7 +29,7 @@
# define _LIBCPP_ASSERTION_HANDLER(message) ((void)0)
#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
-# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_ERROR(_LogErrorReason::_HardeningFailure, message)
+# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_ERROR(::std::_LogErrorReason::_HardeningFailure, message)
#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
>From 0993a0822e8fe60b1822eeab4ac67e0467a70bde Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 19:18:26 -0700
Subject: [PATCH 09/14] [libc++] Add missing unsupported attributes to
hardening timezone tests.
Before this patch, these tests fail under `extensive` and `debug`
hardening modes.
---
.../time.zone.exception.ambig/assert.ctor.pass.cpp | 2 ++
.../time.zone.exception.nonexist/assert.ctor.pass.cpp | 2 ++
.../time.zone.members/assert.to_local.pass.cpp | 1 +
.../time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp | 2 ++
.../time.zone.members/assert.to_sys_choose.pass.cpp | 2 ++
5 files changed, 9 insertions(+)
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
index 73e6bf2846f0e..ee2370f5bce25 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
index fdd9f79958f98..5d896c34e4ccd 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
index d9ca1c80751cc..eb0ae4cf4b187 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
index 3a2ff00088676..57b7f8d0f30a0 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
index 65429345ae794..85ce6019fcd55 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
// REQUIRES: has-unix-headers
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
// <chrono>
>From cfbf82e9f04f5898510d8fe4e3f655e486b4c620 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 19:31:43 -0700
Subject: [PATCH 10/14] Regenerate the symbol list for Linux.
---
...wn-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 8c55c4385f6f6..53cda0be90ca9 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -225,6 +225,7 @@
{'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -592,6 +593,7 @@
{'is_defined': True, 'name': '_ZNSt3__110to_wstringEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110to_wstringEy', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__111__call_onceERVmPvPFvS2_E', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__111__log_errorENS_15_LogErrorReasonEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__111__money_getIcE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_SF_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__111__money_getIwE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERwS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERNS9_IwNSA_IwEENSC_IwEEEESJ_SJ_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__111__money_putIcE13__gather_infoEbbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_Ri', 'type': 'FUNC'}
@@ -773,6 +775,7 @@
{'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -953,7 +956,6 @@
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1156,7 +1158,6 @@
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
>From 1e38d401f858e898073d8c16416f6d9af1399793 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 19:40:02 -0700
Subject: [PATCH 11/14] Always log to `stderr` before making any system calls
(which might not succeed).
---
libcxx/src/log_error.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/src/log_error.cpp b/libcxx/src/log_error.cpp
index 53cf3c7aa7ac2..4e695ff380e8e 100644
--- a/libcxx/src/log_error.cpp
+++ b/libcxx/src/log_error.cpp
@@ -24,6 +24,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace {
void log_security_failure(const char* message) noexcept {
+ // Always log the message to `stderr` in case the platform-specific system calls fail.
+ fprintf(stderr, "%s", message);
+
// On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
os_fault_with_payload(
@@ -42,9 +45,6 @@ void log_security_failure(const char* message) noexcept {
openlog("libc++", 0, 0);
syslog(LOG_CRIT, "%s", message);
closelog();
-
-#else
- fprintf(stderr, "%s", message);
#endif
}
>From 78ff152aa8bf58421f10d51318175a27d9257ac2 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 19:57:21 -0700
Subject: [PATCH 12/14] More symbol list updates.
---
...ux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 5 +++--
...erpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 5 +++--
...pc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 5 +++--
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 4b6f3548ce495..6211fa7e181ee 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -170,6 +170,7 @@
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -580,6 +581,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk110to_wstringEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110to_wstringEy', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__call_onceERVmPvPFvS2_E', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk111__log_errorENS_15_LogErrorReasonEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__money_getIcE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_SF_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__money_getIwE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERwS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERNS9_IwNSA_IwEENSC_IwEEEESJ_SJ_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__money_putIcE13__gather_infoEbbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_Ri', 'type': 'FUNC'}
@@ -761,6 +763,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -941,7 +944,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1144,7 +1146,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 2b85596bd87f6..b788ad3631211 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -96,6 +96,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE6do_outERPcPKwS5_RS5_S2_S2_S3_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE9do_lengthERPcPKcS5_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -311,6 +312,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__110to_wstringEx', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__110to_wstringEy', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111__call_onceERVmPvPFvS2_E', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111__log_errorENS_15_LogErrorReasonEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111regex_errorC1ENS_15regex_constants10error_typeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111regex_errorC2ENS_15regex_constants10error_typeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111regex_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -410,6 +412,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -418,7 +421,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -503,7 +505,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 6ebdab96ed455..7b75b803bd30f 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -96,6 +96,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE6do_outERPcPKwS5_RS5_S2_S2_S3_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE9do_lengthERPcPKcS5_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -311,6 +312,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__110to_wstringEx', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__110to_wstringEy', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111__call_onceERVmPvPFvS2_E', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111__log_errorENS_15_LogErrorReasonEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111regex_errorC1ENS_15regex_constants10error_typeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111regex_errorC2ENS_15regex_constants10error_typeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__111regex_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -410,6 +412,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -418,7 +421,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -503,7 +505,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
>From 0da96f3bbe1b3b136d246129f792cdb5967cbe27 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 19:58:46 -0700
Subject: [PATCH 13/14] More symbol list updates.
---
...ux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 45f3d7c5904e8..bf59b2d57d854 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -170,6 +170,7 @@
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -580,6 +581,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk110to_wstringEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110to_wstringEy', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__call_onceERVmPvPFvS2_E', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk111__log_errorENS_15_LogErrorReasonEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__money_getIcE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_SF_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__money_getIwE13__gather_infoEbRKNS_6localeERNS_10money_base7patternERwS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERNS9_IwNSA_IwEENSC_IwEEEESJ_SJ_Ri', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk111__money_putIcE13__gather_infoEbbRKNS_6localeERNS_10money_base7patternERcS8_RNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEESF_SF_Ri', 'type': 'FUNC'}
@@ -761,6 +763,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -941,7 +944,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1144,7 +1146,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
>From f7325150084f4792e782c9c7a2c40b195a5fc40c Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Sat, 12 Jul 2025 20:05:34 -0700
Subject: [PATCH 14/14] Undo accidental diff
---
libcxxabi/src/CMakeLists.txt | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt
index 0a6fc892a4f69..0675577aed6a1 100644
--- a/libcxxabi/src/CMakeLists.txt
+++ b/libcxxabi/src/CMakeLists.txt
@@ -172,11 +172,12 @@ if (LIBCXXABI_USE_LLVM_UNWINDER)
target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared)
endif()
endif()
-target_link_libraries(cxxabi_shared_objects PRIVATE cxx-headers ${LIBCXXABI_LIBRARIES})
+target_link_libraries(cxxabi_shared_objects
+ PUBLIC cxxabi-headers
+ PRIVATE cxx-headers runtimes-libc-headers ${LIBCXXABI_LIBRARIES})
if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG)
target_link_libraries(cxxabi_shared_objects PRIVATE ${LIBCXXABI_BUILTINS_LIBRARY})
endif()
-target_link_libraries(cxxabi_shared_objects PUBLIC cxxabi-headers)
set_target_properties(cxxabi_shared_objects
PROPERTIES
CXX_EXTENSIONS OFF
@@ -215,7 +216,7 @@ if (ZOS)
endif ()
target_link_libraries(cxxabi_shared
- PUBLIC cxxabi_shared_objects
+ PUBLIC cxxabi_shared_objects runtimes-libc-shared
PRIVATE ${LIBCXXABI_LIBRARIES})
if (LIBCXXABI_ENABLE_SHARED)
@@ -274,8 +275,9 @@ if (LIBCXXABI_USE_LLVM_UNWINDER AND LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC
target_link_libraries(cxxabi_static_objects PUBLIC unwind_static_objects) # propagate usage requirements
target_sources(cxxabi_static_objects PUBLIC $<TARGET_OBJECTS:unwind_static_objects>)
endif()
-target_link_libraries(cxxabi_static_objects PRIVATE cxx-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
-target_link_libraries(cxxabi_static_objects PUBLIC cxxabi-headers)
+target_link_libraries(cxxabi_static_objects
+ PUBLIC cxxabi-headers
+ PRIVATE cxx-headers runtimes-libc-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
set_target_properties(cxxabi_static_objects
PROPERTIES
CXX_EXTENSIONS OFF
@@ -311,7 +313,7 @@ endif()
add_library(cxxabi_static STATIC)
if (LIBCXXABI_USE_LLVM_UNWINDER AND NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
- target_link_libraries(cxxabi_static PUBLIC unwind_static)
+ target_link_libraries(cxxabi_static PUBLIC unwind_static runtimes-libc-static)
endif()
set_target_properties(cxxabi_static
PROPERTIES
More information about the libcxx-commits
mailing list