aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include')
-rw-r--r--libcxx/include/CMakeLists.txt2
-rw-r--r--libcxx/include/__config191
-rw-r--r--libcxx/include/__configuration/experimental.h37
-rw-r--r--libcxx/include/__configuration/hardening.h181
-rw-r--r--libcxx/include/__configuration/language.h3
-rw-r--r--libcxx/include/__vector/vector.h71
-rw-r--r--libcxx/include/module.modulemap.in2
7 files changed, 253 insertions, 234 deletions
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 09d4552..3845ec8 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -328,6 +328,8 @@ set(files
__configuration/abi.h
__configuration/availability.h
__configuration/compiler.h
+ __configuration/experimental.h
+ __configuration/hardening.h
__configuration/language.h
__configuration/platform.h
__coroutine/coroutine_handle.h
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 357f77b..e907961 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -14,6 +14,8 @@
#include <__configuration/abi.h>
#include <__configuration/availability.h>
#include <__configuration/compiler.h>
+#include <__configuration/experimental.h>
+#include <__configuration/hardening.h>
#include <__configuration/language.h>
#include <__configuration/platform.h>
@@ -38,195 +40,6 @@
# define _LIBCPP_FREESTANDING
# endif
-// NOLINTNEXTLINE(libcpp-cpp-version-check)
-# if __cplusplus < 201103L
-# define _LIBCPP_CXX03_LANG
-# endif
-
-# if __has_feature(experimental_library)
-# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
-# define _LIBCPP_ENABLE_EXPERIMENTAL
-# endif
-# endif
-
-// Incomplete features get their own specific disabling flags. This makes it
-// easier to grep for target specific flags once the feature is complete.
-# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
-# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
-# else
-# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
-# endif
-
-# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-
-// HARDENING {
-
-// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
-// Since hardening went through several changes (many of which impacted user-facing macros),
-// we're keeping these checks around for a bit longer than usual. Failure to properly configure
-// hardening results in checks being dropped silently, which is a pretty big deal.
-# if defined(_LIBCPP_ENABLE_ASSERTIONS)
-# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-# if defined(_LIBCPP_ENABLE_HARDENED_MODE)
-# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-# if defined(_LIBCPP_ENABLE_SAFE_MODE)
-# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-# if defined(_LIBCPP_ENABLE_DEBUG_MODE)
-# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-
-// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
-//
-// - `_LIBCPP_HARDENING_MODE_NONE`;
-// - `_LIBCPP_HARDENING_MODE_FAST`;
-// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
-// - `_LIBCPP_HARDENING_MODE_DEBUG`.
-//
-// These values have the following effects:
-//
-// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
-//
-// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
-// that can be done with relatively little runtime overhead in constant time;
-//
-// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
-// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
-// but are not necessarily security-critical;
-//
-// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
-// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
-// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
-
-// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
-// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
-//
-// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
-// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
-// - the sentinel is reachable from the begin iterator;
-// - TODO(hardening): both iterators refer to the same container.
-//
-// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
-// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
-// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
-// `optional` and `function` are considered one-element containers for the purposes of this check.
-//
-// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
-// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
-// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
-// compiler optimizations).
-//
-// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
-// given ranges do not overlap.
-//
-// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
-// was allocated by the given allocator). Violating this category typically results in a memory leak.
-//
-// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
-// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
-// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
-// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
-// otherwise create an immediate security issue.
-//
-// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
-// the containers have compatible allocators.
-//
-// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
-// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
-// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
-// a string view where only a subset of elements is possible to access). This category is for assertions violating
-// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
-// user code.
-//
-// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
-// be benign in our implementation.
-//
-// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
-// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
-// thus, this would often be a heuristic check and it might be quite expensive.
-//
-// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
-// user input.
-//
-// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
-
-// clang-format off
-# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
-# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
-# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
-# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
-// clang-format on
-
-# ifndef _LIBCPP_HARDENING_MODE
-
-# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
-# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
-`__config_site` header, please make sure your installation of libc++ is not broken.
-# endif
-
-# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
-# endif
-
-# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && \
- _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
- _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
- _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
-# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
-_LIBCPP_HARDENING_MODE_NONE, \
-_LIBCPP_HARDENING_MODE_FAST, \
-_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
-
-# else
-# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# error "Assertion semantics are an experimental feature."
-# endif
-# if defined(_LIBCPP_CXX03_LANG)
-# error "Assertion semantics are not available in the C++03 mode."
-# endif
-
-# endif // _LIBCPP_ASSERTION_SEMANTIC
-
-// } HARDENING
-
# define _LIBCPP_TOSTRING2(x) #x
# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
diff --git a/libcxx/include/__configuration/experimental.h b/libcxx/include/__configuration/experimental.h
new file mode 100644
index 0000000..d14df3e
--- /dev/null
+++ b/libcxx/include/__configuration/experimental.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___CONFIGURATION_EXPERIMENTAL_H
+#define _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
+
+#include <__config_site>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+#if __has_feature(experimental_library)
+# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
+# define _LIBCPP_ENABLE_EXPERIMENTAL
+# endif
+#endif
+
+// Incomplete features get their own specific disabling flags. This makes it
+// easier to grep for target specific flags once the feature is complete.
+#if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
+# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
+#else
+# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
+#endif
+
+#define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+#define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+#define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+#define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+
+#endif // _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
diff --git a/libcxx/include/__configuration/hardening.h b/libcxx/include/__configuration/hardening.h
new file mode 100644
index 0000000..bc2a8d0
--- /dev/null
+++ b/libcxx/include/__configuration/hardening.h
@@ -0,0 +1,181 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___CONFIGURATION_HARDENING_H
+#define _LIBCPP___CONFIGURATION_HARDENING_H
+
+#include <__config_site>
+#include <__configuration/experimental.h>
+#include <__configuration/language.h>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
+// Since hardening went through several changes (many of which impacted user-facing macros),
+// we're keeping these checks around for a bit longer than usual. Failure to properly configure
+// hardening results in checks being dropped silently, which is a pretty big deal.
+#if defined(_LIBCPP_ENABLE_ASSERTIONS)
+# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+#if defined(_LIBCPP_ENABLE_HARDENED_MODE)
+# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+#if defined(_LIBCPP_ENABLE_SAFE_MODE)
+# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
+# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+
+// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
+//
+// - `_LIBCPP_HARDENING_MODE_NONE`;
+// - `_LIBCPP_HARDENING_MODE_FAST`;
+// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
+// - `_LIBCPP_HARDENING_MODE_DEBUG`.
+//
+// These values have the following effects:
+//
+// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
+//
+// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
+// that can be done with relatively little runtime overhead in constant time;
+//
+// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
+// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
+// but are not necessarily security-critical;
+//
+// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
+// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
+// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
+
+// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
+// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
+//
+// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
+// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
+// - the sentinel is reachable from the begin iterator;
+// - TODO(hardening): both iterators refer to the same container.
+//
+// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
+// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
+// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
+// `optional` and `function` are considered one-element containers for the purposes of this check.
+//
+// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
+// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
+// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
+// compiler optimizations).
+//
+// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
+// given ranges do not overlap.
+//
+// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
+// was allocated by the given allocator). Violating this category typically results in a memory leak.
+//
+// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
+// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
+// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
+// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
+// otherwise create an immediate security issue.
+//
+// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
+// the containers have compatible allocators.
+//
+// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
+// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
+// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
+// a string view where only a subset of elements is possible to access). This category is for assertions violating
+// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
+// user code.
+//
+// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
+// be benign in our implementation.
+//
+// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
+// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
+// thus, this would often be a heuristic check and it might be quite expensive.
+//
+// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
+// user input.
+//
+// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
+
+// clang-format off
+# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
+# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
+# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
+# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
+// clang-format on
+
+#ifndef _LIBCPP_HARDENING_MODE
+
+# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
+# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
+`__config_site` header, please make sure your installation of libc++ is not broken.
+# endif
+
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
+#endif
+
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
+# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
+_LIBCPP_HARDENING_MODE_NONE, \
+_LIBCPP_HARDENING_MODE_FAST, \
+_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
+
+#else
+
+# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+# error "Assertion semantics are an experimental feature."
+# endif
+# if defined(_LIBCPP_CXX03_LANG)
+# error "Assertion semantics are not available in the C++03 mode."
+# endif
+
+#endif // _LIBCPP_ASSERTION_SEMANTIC
+
+#endif // _LIBCPP___CONFIGURATION_HARDENING_H
diff --git a/libcxx/include/__configuration/language.h b/libcxx/include/__configuration/language.h
index 9c224dfa..26e87f8 100644
--- a/libcxx/include/__configuration/language.h
+++ b/libcxx/include/__configuration/language.h
@@ -18,6 +18,9 @@
// NOLINTBEGIN(libcpp-cpp-version-check)
#ifdef __cplusplus
+# if __cplusplus < 201103L
+# define _LIBCPP_CXX03_LANG
+# endif
# if __cplusplus <= 201103L
# define _LIBCPP_STD_VER 11
# elif __cplusplus <= 201402L
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 316d3a9..a100b16 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -664,9 +664,6 @@ private:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __make_iter(pointer __p) _NOEXCEPT {
#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
// Bound the iterator according to the capacity, rather than the size.
@@ -971,36 +968,6 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __
__tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
}
-// Default constructs __n objects starting at __end_
-// throws if construction throws
-// Postcondition: size() == size() + __n
-// Exception safety: strong.
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n) {
- if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
- this->__construct_at_end(__n);
- else {
- __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
- __v.__construct_at_end(__n);
- __swap_out_circular_buffer(__v);
- }
-}
-
-// Default constructs __n objects starting at __end_
-// throws if construction throws
-// Postcondition: size() == size() + __n
-// Exception safety: strong.
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) {
- if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
- this->__construct_at_end(__n, __x);
- else {
- __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
- __v.__construct_at_end(__n, __x);
- __swap_out_circular_buffer(__v);
- }
-}
-
template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x)
#if _LIBCPP_STD_VER >= 17
@@ -1402,21 +1369,35 @@ vector<_Tp, _Allocator>::__insert_with_size(
}
template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz) {
- size_type __cs = size();
- if (__cs < __sz)
- this->__append(__sz - __cs);
- else if (__cs > __sz)
- this->__destruct_at_end(this->__begin_ + __sz);
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size) {
+ size_type __current_size = size();
+ if (__current_size < __new_size) {
+ if (__new_size <= capacity()) {
+ __construct_at_end(__new_size - __current_size);
+ } else {
+ __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_);
+ __v.__construct_at_end(__new_size - __current_size);
+ __swap_out_circular_buffer(__v);
+ }
+ } else if (__current_size > __new_size) {
+ this->__destruct_at_end(this->__begin_ + __new_size);
+ }
}
template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) {
- size_type __cs = size();
- if (__cs < __sz)
- this->__append(__sz - __cs, __x);
- else if (__cs > __sz)
- this->__destruct_at_end(this->__begin_ + __sz);
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size, const_reference __x) {
+ size_type __current_size = size();
+ if (__current_size < __new_size) {
+ if (__new_size <= capacity())
+ __construct_at_end(__new_size - __current_size, __x);
+ else {
+ __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_);
+ __v.__construct_at_end(__new_size - __current_size, __x);
+ __swap_out_circular_buffer(__v);
+ }
+ } else if (__current_size > __new_size) {
+ this->__destruct_at_end(this->__begin_ + __new_size);
+ }
}
template <class _Tp, class _Allocator>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 2266a1d..85fe88af 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -6,6 +6,8 @@ module std_config [system] {
textual header "__configuration/abi.h"
textual header "__configuration/availability.h"
textual header "__configuration/compiler.h"
+ textual header "__configuration/experimental.h"
+ textual header "__configuration/hardening.h"
textual header "__configuration/language.h"
textual header "__configuration/platform.h"
textual header "version"