Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[libc++][hardening] Introduce assertion semantics#148268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

var-const
Copy link
Member

@var-constvar-const commentedJul 11, 2025
edited
Loading

Assertion semantics closely mimic C++26 Contracts evaluation semantics. This brings our implementation closer in line with C++26 Library Hardening (one particular benefit is that using theobserve semantic makes adopting hardening easier for projects).

@github-actionsGitHub Actions
Copy link

github-actionsbot commentedJul 11, 2025
edited
Loading

✅ With the latest revision this PR passed the C/C++ code formatter.

@var-constvar-const changed the titlevarconst/hardening semantics introduce[libc++][hardening] Introduce assertion semanticsJul 13, 2025
@var-constvar-const marked this pull request as ready for reviewJuly 13, 2025 03:07
@var-constvar-const requested review froma team ascode ownersJuly 13, 2025 03:07
@var-constvar-const added libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. hardeningIssues related to the hardening effort labelsJul 13, 2025
@llvmbot
Copy link
Member

llvmbot commentedJul 13, 2025
edited
Loading

@llvm/pr-subscribers-github-workflow
@llvm/pr-subscribers-libcxxabi

@llvm/pr-subscribers-libcxx

Author: Konstantin Varlamov (var-const)

Changes
  • [libc++][hardening][NFC] Introduce_LIBCPP_VERBOSE_TRAP macro.
  • [libc++][hardening] Introduce a dylib function to log hardening errors.
  • [libc++][hardening] Introduce assertion semantics.

Patch is 78.09 KiB, truncated to 20.00 KiB below, full version:https://github.com/llvm/llvm-project/pull/148268.diff

38 Files Affected:

  • (modified) libcxx/include/CMakeLists.txt (+3)
  • (modified) libcxx/include/__config (+34)
  • (modified) libcxx/include/__configuration/availability.h (+5)
  • (added) libcxx/include/__cxx03/__verbose_trap (+36)
  • (added) libcxx/include/__log_error (+50)
  • (added) libcxx/include/__verbose_trap (+36)
  • (modified) libcxx/include/module.modulemap.in (+6)
  • (modified) libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist (+3-2)
  • (modified) libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist (+3-2)
  • (modified) libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist (+3-2)
  • (modified) libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist (+3-2)
  • (modified) libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist (+3-2)
  • (modified) libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist (+3-2)
  • (modified) libcxx/src/CMakeLists.txt (+1)
  • (added) libcxx/src/log_error.cpp (+61)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp (+15-6)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp (+3-3)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp (+2-2)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp (+4-1)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp (+2-2)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp (+3-3)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp (+2-1)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp (+2-2)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp (+10-8)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp (+2-2)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp (+4-4)
  • (modified) libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp (+2-2)
  • (modified) libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp (+5-4)
  • (modified) libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp (+1-1)
  • (modified) libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp (+2)
  • (modified) libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp (+2)
  • (modified) libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp (+1)
  • (modified) libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp (+2)
  • (modified) libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp (+2)
  • (modified) libcxx/test/support/check_assertion.h (+113-18)
  • (modified) libcxx/utils/libcxx/test/features.py (+8)
  • (modified) libcxx/vendor/llvm/default_assertion_handler.in (+19-15)
  • (modified) libcxxabi/src/demangle/DemangleConfig.h (+7)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txtindex c8e6d28584623..7052716bbb6f0 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_error   __math/abs.h   __math/copysign.h   __math/error_functions.h@@ -944,6 +945,7 @@ set(files   __vector/vector_bool.h   __vector/vector_bool_formatter.h   __verbose_abort+  __verbose_trap   algorithm   any   array@@ -1569,6 +1571,7 @@ set(files   __cxx03/__utility/unreachable.h   __cxx03/__variant/monostate.h   __cxx03/__verbose_abort+  __cxx03/__verbose_trap   __cxx03/algorithm   __cxx03/array   __cxx03/atomicdiff --git a/libcxx/include/__config b/libcxx/include/__configindex d940461c30234..ef0c8b48b658b 100644--- a/libcxx/include/__config+++ b/libcxx/include/__config@@ -147,6 +147,40 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \ _LIBCPP_HARDENING_MODE_DEBUG #  endif+// 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;+// - 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)+#  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) #xdiff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.hindex ae58e36b508b4..5de0b98ba22a9 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 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/__cxx03/__verbose_trap b/libcxx/include/__cxx03/__verbose_trapnew file mode 100644index 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_TRAPdiff --git a/libcxx/include/__log_error b/libcxx/include/__log_errornew file mode 100644index 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_ERRORdiff --git a/libcxx/include/__verbose_trap b/libcxx/include/__verbose_trapnew file mode 100644index 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_TRAPdiff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.inindex 45b9c72a05b82..8d29bded96169 100644--- a/libcxx/include/module.modulemap.in+++ b/libcxx/include/module.modulemap.in@@ -2353,9 +2353,15 @@ module std [system] {     header "__std_mbstate_t.h"     export *   }+  module log_error {+    header "__log_error"+  }   module verbose_abort {     header "__verbose_abort"   }+  module verbose_trap {+    header "__verbose_trap"+  }   module internal_assert {     header "__assert"     export *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.abilistindex 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/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilistindex 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.abilistindex 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_cla...[truncated]

#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This isn't very pretty, but I can't think of a better way, assuming we don't want to add new functionality to the frozen headers.

ldionne reacted with thumbs up emoji
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This looks reasonable to me.

@var-constvar-constforce-pushed thevarconst/hardening-semantics-introduce branch fromba3053d to2ad957bCompareJuly 14, 2025 18:22

.. _assertion-semantics:

Assertion semantics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

General comment: we need to mention (or at least plan for) what happens when C++26 Contracts are implemented. In particular, there will be a time when Clang and libc++ will implement Contracts and the Contracts runtime (class std::contract_violation, etc). Furthermore, we'll want libc++ to be a valid C++26Hardened Implementation, which requires that hardening failures be treated as contract violations.

When that's the case, what should happen with_LIBCPP_ASSERTION_SEMANTIC?

Copy link
MemberAuthor

@var-constvar-constJul 14, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think our design is constrained by the fact that we want to support hardening in older language modes where Contracts would not be available even when using a new compiler (after all, a major motivation for hardening is makingexisting code bases more secure). Support for theobserve semantic is important for adopting hardening in production, so I think it would be a significant limitation if this semantic were only available for projects that can use very recent compiler versions. It makes having some form of assertion semantics unavoidable.

I also think it makes sense to have assertion semantics mimic the actual Contracts semantics -- it's simple(r) conceptually and might make migrating to Contracts easier. We could have e.g. a boolean flag ("observe"/"not observe") instead but I think it would be creating unnecessary differences without buying us much.

If this is the case, then we cannot escape the situation where libc++ assertion semantics and actual Contracts evaluation semantics "clash" and need to choose the best (in the sense of "lesser of several evils") alternative. Summarizing our offline discussion, I think when a user sets the assertion semantic in an environment where Contract semantics are available, we can:

  • A. Make this an error.
  • B. Allow the Contracts semantic to silently take precedence (effectively override) the assertion semantic.
  • C. Do either A or B based on whether the assertion semantic matches the Contract semantic (if they match, setting the assertion semantic is a no-op, if they don't match, produce an error). While it's not impossible for a project to use different semantics based on the language mode, it seems very unlikely in practice.

(C) seems like the better option -- (A) would make it painful for projects to support more than one language mode, and (B) might allow silently downgrading the semantic to a non-terminating one, for example. IIUC, the evaluation semantic can be chosen at runtime, making it hard or impossible to catch mismatch, but these cases should be relatively rare, and I think (C) should generally cover this.

This also means that we would want to support assertion semantics long term, having support for Contracts doesn't automatically deprecate them.

ldionne reacted with thumbs up emoji
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This looks reasonable to me.

Copy link
Member

@ldionneldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This LGTM after rebasing ontomain.

Assertion semantics closely mimic C++26 Contracts evaluation semantics.This brings our implementation closer in line with C++26 LibraryHardening (one particular benefit is that using the observe semanticmakes adopting hardening easier for projects).
@var-constvar-constforce-pushed thevarconst/hardening-semantics-introduce branch from17b5a0d tof187236CompareJuly 15, 2025 05:34
@llvmbotllvmbot added libc++abilibc++abi C++ Runtime Library. Not libc++. github:workflow labelsJul 15, 2025
@var-constvar-const merged commit7345508 intollvm:mainJul 15, 2025
82 checks passed
philnik777 added a commit that referenced this pull requestJul 15, 2025
philnik777 added a commit that referenced this pull requestJul 15, 2025
llvm-syncbot pushed a commit to arm/arm-toolchain that referenced this pull requestJul 15, 2025
… (#148822)Revertsllvm/llvm-project#148268It looks like this was based on #148266, which I reverted in #148787.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@ldionneldionneldionne approved these changes

Assignees
No one assigned
Labels
github:workflowhardeningIssues related to the hardening effortlibc++abilibc++abi C++ Runtime Library. Not libc++.libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@var-const@llvmbot@ldionne

[8]ページ先頭

©2009-2025 Movatter.jp