aboutsummaryrefslogtreecommitdiff
path: root/lib/libcxx/include/__config
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-04-26 15:33:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-05-08 19:37:29 -0700
commit06ee65af9ed6aa5ee4d1d7f4fab9d7acecf66e76 (patch)
tree1316711b92a43dd5c599e425b8693fa8e1e0c0b7 /lib/libcxx/include/__config
parentbc6ebc6f2597fda1f98842c6f545751fef2a5334 (diff)
downloadzig-06ee65af9ed6aa5ee4d1d7f4fab9d7acecf66e76.tar.gz
zig-06ee65af9ed6aa5ee4d1d7f4fab9d7acecf66e76.zip
libcxx: update to LLVM 18
release/18.x branch, commit 78b99c73ee4b96fe9ce0e294d4632326afb2db42 This adds the flag `-D_LIBCPP_HARDENING_MODE` which is determined based on the Zig optimization mode. This commit also fixes libunwind, libcxx, and libcxxabi to properly report sub compilation errors.
Diffstat (limited to 'lib/libcxx/include/__config')
-rw-r--r--lib/libcxx/include/__config693
1 files changed, 386 insertions, 307 deletions
diff --git a/lib/libcxx/include/__config b/lib/libcxx/include/__config
index fc76e6bd13..630861acaf 100644
--- a/lib/libcxx/include/__config
+++ b/lib/libcxx/include/__config
@@ -12,16 +12,21 @@
/* zig patch: instead of including __config_site, zig adds -D flags when compiling */
-#if defined(_MSC_VER) && !defined(__clang__)
-# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-# endif
-#endif
-
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
#endif
+#if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
+# pragma clang deprecated( \
+ _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES, \
+ "_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES is deprecated in LLVM 18 and will be removed in LLVM 19")
+#endif
+#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
+# pragma clang deprecated( \
+ _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES, \
+ "_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES is deprecated in LLVM 18 and will be removed in LLVM 19")
+#endif
+
#if defined(__apple_build_version__)
// Given AppleClang XX.Y.Z, _LIBCPP_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403)
# define _LIBCPP_COMPILER_CLANG_BASED
@@ -31,24 +36,37 @@
# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
#elif defined(__GNUC__)
# define _LIBCPP_COMPILER_GCC
+# define _LIBCPP_GCC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
#endif
#ifdef __cplusplus
+// Warn if a compiler version is used that is not supported anymore
+// LLVM RELEASE Update the minimum compiler versions
+# if defined(_LIBCPP_CLANG_VER)
+# if _LIBCPP_CLANG_VER < 1600
+# warning "Libc++ only supports Clang 16 and later"
+# endif
+# elif defined(_LIBCPP_APPLE_CLANG_VER)
+# if _LIBCPP_APPLE_CLANG_VER < 1500
+# warning "Libc++ only supports AppleClang 15 and later"
+# endif
+# elif defined(_LIBCPP_GCC_VER)
+# if _LIBCPP_GCC_VER < 1300
+# warning "Libc++ only supports GCC 13 and later"
+# endif
+# endif
+
// The attributes supported by clang are documented at https://clang.llvm.org/docs/AttributeReference.html
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
// defined to XXYYZZ.
-# define _LIBCPP_VERSION 170000
+# define _LIBCPP_VERSION 180100
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
-// Valid C++ identifier that revs with every libc++ version. This can be used to
-// generate identifiers that must be unique for every released libc++ version.
-# define _LIBCPP_VERSIONED_IDENTIFIER _LIBCPP_CONCAT(v, _LIBCPP_VERSION)
-
# if __STDC_HOSTED__ == 0
# define _LIBCPP_FREESTANDING
# endif
@@ -170,7 +188,7 @@
# endif
// Feature macros for disabling pre ABI v1 features. All of these options
// are deprecated.
-# if defined(__FreeBSD__)
+# if defined(__FreeBSD__) && __FreeBSD__ < 14
# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
# endif
// For XCOFF linkers, we have problems if we see a weak hidden version of a symbol
@@ -182,17 +200,22 @@
# endif
# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2
-// Enable additional explicit instantiations of iostreams components. This
-// reduces the number of weak definitions generated in programs that use
-// iostreams by providing a single strong definition in the shared library.
-# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
-
// Define a key function for `bad_function_call` in the library, to centralize
// its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies.
# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
# endif
+// We had some bugs where we use [[no_unique_address]] together with construct_at,
+// which causes UB as the call on construct_at could write to overlapping subobjects
+//
+// https://github.com/llvm/llvm-project/issues/70506
+// https://github.com/llvm/llvm-project/issues/70494
+//
+// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions.
+// The macro below is used for all classes whose ABI have changed as part of fixing these bugs.
+# define _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS __attribute__((__abi_tag__("llvm18_nua")))
+
// Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's
// within the bounds of the original container and asserts it on every dereference.
//
@@ -208,27 +231,39 @@
// HARDENING {
-# ifndef _LIBCPP_ENABLE_ASSERTIONS
-# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
-# endif
-# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
-# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
+// TODO(hardening): deprecate this in LLVM 19.
+// This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes)
+// equivalent to setting the extensive mode.
+# ifdef _LIBCPP_ENABLE_ASSERTIONS
+# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
+# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
+# endif
+# if _LIBCPP_ENABLE_ASSERTIONS
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
+# endif
# endif
-// NOTE: These modes are experimental and are not stable yet in LLVM 17. Please refrain from using them and use the
-// documented libc++ "safe" mode instead.
+// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
//
-// Enables the hardened mode which consists of all checks intended to be used in production. Hardened mode prioritizes
-// security-critical checks that can be done with relatively little overhead in constant time. Mutually exclusive with
-// `_LIBCPP_ENABLE_DEBUG_MODE`.
+// - `_LIBCPP_HARDENING_MODE_NONE`;
+// - `_LIBCPP_HARDENING_MODE_FAST`;
+// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
+// - `_LIBCPP_HARDENING_MODE_DEBUG`.
//
-// #define _LIBCPP_ENABLE_HARDENED_MODE 1
-
-// Enables the debug mode which contains all the checks from the hardened mode and additionally more expensive checks
-// that may affect the complexity of algorithms. The debug mode is intended to be used for testing, not in production.
-// Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE`.
+// 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;
//
-// #define _LIBCPP_ENABLE_DEBUG_MODE 1
+// - `_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.
@@ -243,77 +278,124 @@
// 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.
-# ifndef _LIBCPP_ENABLE_HARDENED_MODE
-# define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT
-# endif
-# if _LIBCPP_ENABLE_HARDENED_MODE != 0 && _LIBCPP_ENABLE_HARDENED_MODE != 1
-# error "_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1."
-# endif
-
-# ifndef _LIBCPP_ENABLE_DEBUG_MODE
-# define _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT
-# endif
-# if _LIBCPP_ENABLE_DEBUG_MODE != 0 && _LIBCPP_ENABLE_DEBUG_MODE != 1
-# error "_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1."
-# endif
+// 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
-# if _LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE
-# error "Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled."
+# ifndef _LIBCPP_HARDENING_MODE
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
# endif
-# if _LIBCPP_ENABLE_ASSERTIONS && (_LIBCPP_ENABLE_HARDENED_MODE || _LIBCPP_ENABLE_DEBUG_MODE)
-# error \
- "_LIBCPP_ENABLE_ASSERTIONS is mutually exclusive with _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE."
+# 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
-// Hardened mode checks.
-
// clang-format off
-# if _LIBCPP_ENABLE_HARDENED_MODE
+// Fast hardening mode checks.
+
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
// Enabled checks.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
// Disabled checks.
+// On most modern platforms, dereferencing a null pointer does not lead to an actual memory access.
+# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
// vulnerability.
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
-// Debug mode checks.
+// Extensive hardening mode checks.
-# elif _LIBCPP_ENABLE_DEBUG_MODE
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
-// All checks enabled.
-# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
-# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
-# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
-# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
-# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
-# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
+// Enabled checks.
+# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
+// Disabled checks.
+# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
-// Safe mode checks.
+// Debug hardening mode checks.
-# elif _LIBCPP_ENABLE_ASSERTIONS
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
// All checks enabled.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
@@ -324,12 +406,18 @@
// All checks disabled.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
-# endif // _LIBCPP_ENABLE_HARDENED_MODE
+# endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
// clang-format on
// } HARDENING
@@ -419,10 +507,9 @@
// easier to grep for target specific flags once the feature is complete.
# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
# define _LIBCPP_HAS_NO_INCOMPLETE_PSTL
-# endif
-
-# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
# define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN
+# define _LIBCPP_HAS_NO_INCOMPLETE_TZDB
+# define _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM
# endif
// Need to detect which libc we're using if we're on Linux.
@@ -439,48 +526,19 @@
# include <features.h> // for __NATIVE_ASCII_F
# endif
-# ifdef __LITTLE_ENDIAN__
-# if __LITTLE_ENDIAN__
-# define _LIBCPP_LITTLE_ENDIAN
-# endif // __LITTLE_ENDIAN__
-# endif // __LITTLE_ENDIAN__
-
-# ifdef __BIG_ENDIAN__
-# if __BIG_ENDIAN__
-# define _LIBCPP_BIG_ENDIAN
-# endif // __BIG_ENDIAN__
-# endif // __BIG_ENDIAN__
-
-# ifdef __BYTE_ORDER__
-# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-# define _LIBCPP_LITTLE_ENDIAN
-# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-# define _LIBCPP_BIG_ENDIAN
-# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-# endif // __BYTE_ORDER__
+# ifndef __BYTE_ORDER__
+# error \
+ "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform"
+# endif
-# ifdef __FreeBSD__
-# include <osreldate.h>
-# include <sys/endian.h>
-# if _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_LITTLE_ENDIAN
-# else // _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_BIG_ENDIAN
-# endif // _BYTE_ORDER == _LITTLE_ENDIAN
-# endif // __FreeBSD__
-
-# if defined(__NetBSD__) || defined(__OpenBSD__)
-# include <sys/endian.h>
-# if _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_LITTLE_ENDIAN
-# else // _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_BIG_ENDIAN
-# endif // _BYTE_ORDER == _LITTLE_ENDIAN
-# endif // defined(__NetBSD__) || defined(__OpenBSD__)
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define _LIBCPP_LITTLE_ENDIAN
+# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define _LIBCPP_BIG_ENDIAN
+# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# if defined(_WIN32)
# define _LIBCPP_WIN32API
-# define _LIBCPP_LITTLE_ENDIAN
# define _LIBCPP_SHORT_WCHAR 1
// Both MinGW and native MSVC provide a "MSVC"-like environment
# define _LIBCPP_MSVCRT_LIKE
@@ -553,23 +611,6 @@
# define _LIBCPP_USING_DEV_RANDOM
# endif
-# if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
-# include <endian.h>
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define _LIBCPP_LITTLE_ENDIAN
-# elif __BYTE_ORDER == __BIG_ENDIAN
-# define _LIBCPP_BIG_ENDIAN
-# else // __BYTE_ORDER == __BIG_ENDIAN
-# error unable to determine endian
-# endif
-# endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
-
-# if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
-# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
-# else
-# define _LIBCPP_NO_CFI
-# endif
-
# ifndef _LIBCPP_CXX03_LANG
# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
@@ -641,11 +682,6 @@ typedef __char32_t char32_t;
# define _LIBCPP_HAS_NO_ASAN
# endif
-// Allow for build-time disabling of unsigned integer sanitization
-# if __has_attribute(no_sanitize)
-# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
-# endif
-
# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
@@ -699,7 +735,7 @@ typedef __char32_t char32_t;
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
# define _LIBCPP_TEMPLATE_VIS
# define _LIBCPP_TEMPLATE_DATA_VIS
-# define _LIBCPP_ENUM_VIS
+# define _LIBCPP_TYPE_VISIBILITY_DEFAULT
# else
@@ -727,20 +763,17 @@ typedef __char32_t char32_t;
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
# endif
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# if __has_attribute(__type_visibility__)
-# define _LIBCPP_TEMPLATE_VIS __attribute__((__type_visibility__("default")))
-# else
-# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default")))
-# endif
+// GCC doesn't support the type_visibility attribute, so we have to keep the visibility attribute on templates
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && !__has_attribute(__type_visibility__)
+# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default")))
# else
# define _LIBCPP_TEMPLATE_VIS
# endif
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__)
-# define _LIBCPP_ENUM_VIS __attribute__((__type_visibility__("default")))
+# define _LIBCPP_TYPE_VISIBILITY_DEFAULT __attribute__((__type_visibility__("default")))
# else
-# define _LIBCPP_ENUM_VIS
+# define _LIBCPP_TYPE_VISIBILITY_DEFAULT
# endif
# endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
@@ -754,22 +787,54 @@ typedef __char32_t char32_t;
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
# endif
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
+# define _LIBCPP_HARDENING_SIG f
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
+# define _LIBCPP_HARDENING_SIG s
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+# define _LIBCPP_HARDENING_SIG d
+# else
+# define _LIBCPP_HARDENING_SIG n // "none"
+# endif
+
+# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# define _LIBCPP_EXCEPTIONS_SIG n
+# else
+# define _LIBCPP_EXCEPTIONS_SIG e
+# endif
+
+# define _LIBCPP_ODR_SIGNATURE \
+ _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION)
+
// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
// on two levels:
// 1. The symbol is given hidden visibility, which ensures that users won't start exporting
// symbols from their dynamic library by means of using the libc++ headers. This ensures
// that those symbols stay private to the dynamic library in which it is defined.
//
-// 2. The symbol is given an ABI tag that changes with each version of libc++. This ensures
-// that no ODR violation can arise from mixing two TUs compiled with different versions
-// of libc++ where we would have changed the definition of a symbol. If the symbols shared
-// the same name, the ODR would require that their definitions be token-by-token equivalent,
-// which basically prevents us from being able to make any change to any function in our
-// headers. Using this ABI tag ensures that the symbol name is "bumped" artificially at
-// each release, which lets us change the definition of these symbols at our leisure.
-// Note that historically, this has been achieved in various ways, including force-inlining
-// all functions or giving internal linkage to all functions. Both these (previous) solutions
-// suffer from drawbacks that lead notably to code bloat.
+// 2. The symbol is given an ABI tag that encodes the ODR-relevant properties of the library.
+// This ensures that no ODR violation can arise from mixing two TUs compiled with different
+// versions or configurations of libc++ (such as exceptions vs no-exceptions). Indeed, if the
+// program contains two definitions of a function, the ODR requires them to be token-by-token
+// equivalent, and the linker is allowed to pick either definition and discard the other one.
+//
+// For example, if a program contains a copy of `vector::at()` compiled with exceptions enabled
+// *and* a copy of `vector::at()` compiled with exceptions disabled (by means of having two TUs
+// compiled with different settings), the two definitions are both visible by the linker and they
+// have the same name, but they have a meaningfully different implementation (one throws an exception
+// and the other aborts the program). This violates the ODR and makes the program ill-formed, and in
+// practice what will happen is that the linker will pick one of the definitions at random and will
+// discard the other one. This can quite clearly lead to incorrect program behavior.
+//
+// A similar reasoning holds for many other properties that are ODR-affecting. Essentially any
+// property that causes the code of a function to differ from the code in another configuration
+// can be considered ODR-affecting. In practice, we don't encode all such properties in the ABI
+// tag, but we encode the ones that we think are most important: library version, exceptions, and
+// hardening mode.
+//
+// Note that historically, solving this problem has been achieved in various ways, including
+// force-inlining all functions or giving internal linkage to all functions. Both these previous
+// solutions suffer from drawbacks that lead notably to code bloat.
//
// Note that we use _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION to ensure that we don't depend
// on _LIBCPP_HIDE_FROM_ABI methods of classes explicitly instantiated in the dynamic library.
@@ -789,7 +854,7 @@ typedef __char32_t char32_t;
# ifndef _LIBCPP_NO_ABI_TAG
# define _LIBCPP_HIDE_FROM_ABI \
_LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION \
- __attribute__((__abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_VERSIONED_IDENTIFIER))))
+ __attribute__((__abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_ODR_SIGNATURE))))
# else
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
@@ -809,30 +874,23 @@ typedef __char32_t char32_t;
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
# endif
-// Just so we can migrate to the new macros gradually.
+// TODO(LLVM-19): Remove _LIBCPP_INLINE_VISIBILITY and _VSTD, which we're keeping around
+// only to ease the renaming for downstreams.
# define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
+# define _VSTD std
// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
// clang-format off
-# define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
+# define _LIBCPP_BEGIN_NAMESPACE_STD namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { \
+ inline namespace _LIBCPP_ABI_NAMESPACE {
# define _LIBCPP_END_NAMESPACE_STD }}
-# define _VSTD std
-_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
-
-# if _LIBCPP_STD_VER >= 17
-# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
-# else
-# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
-# endif
+# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD \
+ inline namespace __fs { namespace filesystem {
# define _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_STD }}
// clang-format on
-# define _VSTD_FS std::__fs::filesystem
-
# if __has_attribute(__enable_if__)
# define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, "")))
# endif
@@ -841,18 +899,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_HAS_NO_INT128
# endif
-# if __has_attribute(__malloc__)
-# define _LIBCPP_NOALIAS __attribute__((__malloc__))
-# else
-# define _LIBCPP_NOALIAS
-# endif
-
-# if __has_attribute(__using_if_exists__)
-# define _LIBCPP_USING_IF_EXISTS __attribute__((__using_if_exists__))
-# else
-# define _LIBCPP_USING_IF_EXISTS
-# endif
-
# ifdef _LIBCPP_CXX03_LANG
# define _LIBCPP_DECLARE_STRONG_ENUM(x) \
struct _LIBCPP_EXPORTED_FROM_ABI x { \
@@ -860,14 +906,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
// clang-format off
# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
__lx __v_; \
- _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \
- _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
- _LIBCPP_INLINE_VISIBILITY operator int() const { return __v_; } \
+ _LIBCPP_HIDE_FROM_ABI x(__lx __v) : __v_(__v) {} \
+ _LIBCPP_HIDE_FROM_ABI explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
+ _LIBCPP_HIDE_FROM_ABI operator int() const { return __v_; } \
};
// clang-format on
# else // _LIBCPP_CXX03_LANG
-# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x
+# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class x
# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
# endif // _LIBCPP_CXX03_LANG
@@ -1022,44 +1068,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CONSTEXPR_SINCE_CXX23
# endif
-# if __has_cpp_attribute(nodiscard)
-# define _LIBCPP_NODISCARD [[__nodiscard__]]
-# else
-// We can't use GCC's [[gnu::warn_unused_result]] and
-// __attribute__((warn_unused_result)), because GCC does not silence them via
-// (void) cast.
-# define _LIBCPP_NODISCARD
-# endif
-
-// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not
-// specified as such as an extension.
-# if !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
-# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD
-# else
-# define _LIBCPP_NODISCARD_EXT
-# endif
-
-# if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
-# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD
-# else
-# define _LIBCPP_NODISCARD_AFTER_CXX17
-# endif
-
-# if __has_attribute(__no_destroy__)
-# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__))
-# else
-# define _LIBCPP_NO_DESTROY
-# endif
-
# ifndef _LIBCPP_HAS_NO_ASAN
- extern "C" _LIBCPP_EXPORTED_FROM_ABI void
- __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*);
-# if _LIBCPP_CLANG_VER >= 1600
+extern "C" _LIBCPP_EXPORTED_FROM_ABI void
+__sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*);
extern "C" _LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container(
const void*, const void*, const void*, const void*, const void*, const void*);
extern "C" _LIBCPP_EXPORTED_FROM_ABI int
__sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*);
-# endif
# endif
// Try to find out if RTTI is disabled.
@@ -1160,11 +1175,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
# endif
-// Some systems do not provide gets() in their C library, for security reasons.
-# if defined(_LIBCPP_MSVCRT) || (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || defined(__OpenBSD__)
-# define _LIBCPP_C_HAS_NO_GETS
-# endif
-
# if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \
defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__)
# define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
@@ -1188,10 +1198,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# endif
# endif
-# ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-# endif
-
# if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__)
# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__))
# else
@@ -1224,49 +1230,21 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_CONSTINIT
# endif
-# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS)
-# define _LIBCPP_DIAGNOSE_WARNING(...) __attribute__((__diagnose_if__(__VA_ARGS__, "warning")))
-# else
-# define _LIBCPP_DIAGNOSE_WARNING(...)
-# endif
-
-// Use a function like macro to imply that it must be followed by a semicolon
-# if __has_cpp_attribute(fallthrough)
-# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
-# elif __has_attribute(__fallthrough__)
-# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
-# else
-# define _LIBCPP_FALLTHROUGH() ((void)0)
-# endif
-
-# if __has_cpp_attribute(_Clang::__lifetimebound__)
-# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
-# else
-# define _LIBCPP_LIFETIMEBOUND
-# endif
-
-# if __has_attribute(__nodebug__)
-# define _LIBCPP_NODEBUG __attribute__((__nodebug__))
-# else
-# define _LIBCPP_NODEBUG
-# endif
-
-# if __has_attribute(__standalone_debug__)
-# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
-# else
-# define _LIBCPP_STANDALONE_DEBUG
-# endif
-
-# if __has_attribute(__preferred_name__)
-# define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
-# else
-# define _LIBCPP_PREFERRED_NAME(x)
-# endif
-
-# if __has_attribute(__no_sanitize__)
-# define _LIBCPP_NO_SANITIZE(...) __attribute__((__no_sanitize__(__VA_ARGS__)))
+# if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
+// The CUDA SDK contains an unfortunate definition for the __noinline__ macro,
+// which breaks the regular __attribute__((__noinline__)) syntax. Therefore,
+// when compiling for CUDA we use the non-underscored version of the noinline
+// attribute.
+//
+// This is a temporary workaround and we still expect the CUDA SDK team to solve
+// this issue properly in the SDK headers.
+//
+// See https://github.com/llvm/llvm-project/pull/73838 for more details.
+# define _LIBCPP_NOINLINE __attribute__((noinline))
+# elif __has_attribute(__noinline__)
+# define _LIBCPP_NOINLINE __attribute__((__noinline__))
# else
-# define _LIBCPP_NO_SANITIZE(...)
+# define _LIBCPP_NOINLINE
# endif
// We often repeat things just for handling wide characters in the library.
@@ -1279,12 +1257,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__
# endif
-# if defined(_LIBCPP_ABI_MICROSOFT) && __has_declspec_attribute(empty_bases)
-# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
-# else
-# define _LIBCPP_DECLSPEC_EMPTY_BASES
-# endif
-
# if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES)
# define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
# define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
@@ -1303,8 +1275,8 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
// clang-format off
-# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh()\")") _Pragma("push_macro(\"move(int, int)\")") _Pragma("push_macro(\"erase()\")")
-# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh()\")") _Pragma("pop_macro(\"move(int, int)\")") _Pragma("pop_macro(\"erase()\")")
+# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh\")") _Pragma("push_macro(\"move\")") _Pragma("push_macro(\"erase\")")
+# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh\")") _Pragma("pop_macro(\"move\")") _Pragma("pop_macro(\"erase\")")
// clang-format on
# ifndef _LIBCPP_NO_AUTO_LINK
@@ -1328,28 +1300,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_FOPEN_CLOEXEC_MODE
# endif
-// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set
-// of functions used in cstdio may not be available for low API levels when
-// using 64-bit file offsets on LP32.
-# if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24
-# define _LIBCPP_HAS_NO_FGETPOS_FSETPOS
-# endif
-
-# if __has_attribute(__init_priority__)
-# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((__init_priority__(100)))
-# else
-# define _LIBCPP_INIT_PRIORITY_MAX
-# endif
-
-# if __has_attribute(__format__)
-// The attribute uses 1-based indices for ordinary and static member functions.
-// The attribute uses 2-based indices for non-static member functions.
-# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \
- __attribute__((__format__(archetype, format_string_index, first_format_arg_index)))
-# else
-# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */
-# endif
-
# if __has_cpp_attribute(msvc::no_unique_address)
// MSVC implements [[no_unique_address]] as a silent no-op currently.
// (If/when MSVC breaks its C++ ABI, it will be changed to work as intended.)
@@ -1389,20 +1339,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
# endif
-# if defined(_AIX) && !defined(_LIBCPP_COMPILER_GCC)
-# define _LIBCPP_PACKED_BYTE_FOR_AIX _Pragma("pack(1)")
-# define _LIBCPP_PACKED_BYTE_FOR_AIX_END _Pragma("pack(pop)")
-# else
-# define _LIBCPP_PACKED_BYTE_FOR_AIX /* empty */
-# define _LIBCPP_PACKED_BYTE_FOR_AIX_END /* empty */
-# endif
-
-# if __has_attribute(__packed__)
-# define _LIBCPP_PACKED __attribute__((__packed__))
-# else
-# define _LIBCPP_PACKED
-# endif
-
// c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these
// functions is gradually being added to existing C libraries. The conditions
// below check for known C library versions and conditions under which these
@@ -1467,6 +1403,16 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \
_PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig))
+# elif defined(_LIBCPP_COMPILER_CLANG_BASED)
+
+# define _PSTL_PRAGMA_SIMD _Pragma("clang loop vectorize(enable) interleave(enable)")
+# define _PSTL_PRAGMA_DECLARE_SIMD
+# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _Pragma("clang loop vectorize(enable) interleave(enable)")
+# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _Pragma("clang loop vectorize(enable) interleave(enable)")
+# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM)
+# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM)
+# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP)
+
# else // (defined(_OPENMP) && _OPENMP >= 201307)
# define _PSTL_PRAGMA_SIMD
@@ -1481,6 +1427,139 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
+// Optional attributes - these are useful for a better QoI, but not required to be available
+
+# if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
+# else
+# define _LIBCPP_NO_CFI
+# endif
+
+# if __has_attribute(__malloc__)
+# define _LIBCPP_NOALIAS __attribute__((__malloc__))
+# else
+# define _LIBCPP_NOALIAS
+# endif
+
+# if __has_attribute(__using_if_exists__)
+# define _LIBCPP_USING_IF_EXISTS __attribute__((__using_if_exists__))
+# else
+# define _LIBCPP_USING_IF_EXISTS
+# endif
+
+# if __has_cpp_attribute(nodiscard)
+# define _LIBCPP_NODISCARD [[__nodiscard__]]
+# else
+// We can't use GCC's [[gnu::warn_unused_result]] and
+// __attribute__((warn_unused_result)), because GCC does not silence them via
+// (void) cast.
+# define _LIBCPP_NODISCARD
+# endif
+
+// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not
+// specified as such as an extension.
+# if !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
+# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD
+# else
+# define _LIBCPP_NODISCARD_EXT
+# endif
+
+# if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
+# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD
+# else
+# define _LIBCPP_NODISCARD_AFTER_CXX17
+# endif
+
+# if __has_attribute(__no_destroy__)
+# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__))
+# else
+# define _LIBCPP_NO_DESTROY
+# endif
+
+# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS)
+# define _LIBCPP_DIAGNOSE_WARNING(...) __attribute__((__diagnose_if__(__VA_ARGS__, "warning")))
+# else
+# define _LIBCPP_DIAGNOSE_WARNING(...)
+# endif
+
+// Use a function like macro to imply that it must be followed by a semicolon
+# if __has_cpp_attribute(fallthrough)
+# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
+# elif __has_attribute(__fallthrough__)
+# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
+# else
+# define _LIBCPP_FALLTHROUGH() ((void)0)
+# endif
+
+# if __has_cpp_attribute(_Clang::__lifetimebound__)
+# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
+# else
+# define _LIBCPP_LIFETIMEBOUND
+# endif
+
+# if __has_attribute(__nodebug__)
+# define _LIBCPP_NODEBUG __attribute__((__nodebug__))
+# else
+# define _LIBCPP_NODEBUG
+# endif
+
+# if __has_attribute(__standalone_debug__)
+# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
+# else
+# define _LIBCPP_STANDALONE_DEBUG
+# endif
+
+# if __has_attribute(__preferred_name__)
+# define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
+# else
+# define _LIBCPP_PREFERRED_NAME(x)
+# endif
+
+# if __has_attribute(__no_sanitize__)
+# define _LIBCPP_NO_SANITIZE(...) __attribute__((__no_sanitize__(__VA_ARGS__)))
+# else
+# define _LIBCPP_NO_SANITIZE(...)
+# endif
+
+# if __has_attribute(__init_priority__)
+# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((__init_priority__(100)))
+# else
+# define _LIBCPP_INIT_PRIORITY_MAX
+# endif
+
+# if __has_attribute(__format__)
+// The attribute uses 1-based indices for ordinary and static member functions.
+// The attribute uses 2-based indices for non-static member functions.
+# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \
+ __attribute__((__format__(archetype, format_string_index, first_format_arg_index)))
+# else
+# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */
+# endif
+
+# if __has_attribute(__packed__)
+# define _LIBCPP_PACKED __attribute__((__packed__))
+# else
+# define _LIBCPP_PACKED
+# endif
+
+# if defined(_LIBCPP_ABI_MICROSOFT) && __has_declspec_attribute(empty_bases)
+# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
+# else
+# define _LIBCPP_DECLSPEC_EMPTY_BASES
+# endif
+
+// Allow for build-time disabling of unsigned integer sanitization
+# if __has_attribute(no_sanitize) && !defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
+# else
+# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+# endif
+
+// Clang-18 has support for deducing this, but it does not set the FTM.
+# if defined(__cpp_explicit_this_parameter) || (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1800)
+# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
+# endif
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG