aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__config
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/__config')
-rw-r--r--libcxx/include/__config585
1 files changed, 304 insertions, 281 deletions
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 9759d3b9e8e0..7f66042f9025 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -12,12 +12,6 @@
#include <__config_site>
-#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
@@ -31,24 +25,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 180000
# 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
@@ -156,6 +163,11 @@
// The implementation moved to the header, but we still export the symbols from
// the dylib for backwards compatibility.
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
+// Save memory by providing the allocator more freedom to allocate the most
+// efficient size class by dropping the alignment requirements for std::string's
+// pointer from 16 to 8. This changes the output of std::string::max_size,
+// which makes it ABI breaking
+# define _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
# elif _LIBCPP_ABI_VERSION == 1
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
// Enable compiling copies of now inline methods into the dylib to support
@@ -170,7 +182,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,11 +194,6 @@
# 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.
@@ -208,30 +215,39 @@
// HARDENING {
-// TODO(hardening): remove this in LLVM 18.
+// 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 hardened mode.
+// equivalent to setting the extensive mode.
# ifdef _LIBCPP_ENABLE_ASSERTIONS
-# warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_HARDENED_MODE instead."
# 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_ENABLE_HARDENED_MODE 1
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
# endif
# endif
-// 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`.
+// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
//
-// #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`.
+// - `_LIBCPP_HARDENING_MODE_NONE`;
+// - `_LIBCPP_HARDENING_MODE_FAST`;
+// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
+// - `_LIBCPP_HARDENING_MODE_DEBUG`.
//
-// #define _LIBCPP_ENABLE_DEBUG_MODE 1
+// 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.
@@ -246,6 +262,11 @@
// 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.
//
@@ -257,33 +278,39 @@
//
// - `_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
+// 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_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."
+# ifndef _LIBCPP_HARDENING_MODE
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
# endif
-# 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."
+# 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)
@@ -291,13 +318,28 @@
# 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_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
+
+// 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_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
+// Disabled checks.
+# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
+
+// Debug hardening mode checks.
-# elif _LIBCPP_ENABLE_DEBUG_MODE
+# 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_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
@@ -310,12 +352,13 @@
// 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_COMPATIBLE_ALLOCATOR(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
@@ -405,10 +448,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.
@@ -425,48 +467,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__
-
-# 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__
+# 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
-# 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
@@ -539,23 +552,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)
@@ -627,11 +623,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__
@@ -685,7 +676,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
@@ -713,20 +704,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)
@@ -740,22 +728,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.
@@ -775,7 +795,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
@@ -795,30 +815,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
@@ -827,18 +840,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 { \
@@ -846,14 +847,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
@@ -1008,44 +1009,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_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.
@@ -1174,10 +1144,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
@@ -1210,49 +1176,10 @@ __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 __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.
@@ -1265,12 +1192,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
@@ -1314,28 +1235,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.)
@@ -1375,20 +1274,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
@@ -1453,6 +1338,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
@@ -1467,6 +1362,134 @@ __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
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG