aboutsummaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/docs/FeatureTestMacroTable.rst2
-rw-r--r--libcxx/docs/ReleaseNotes/22.rst2
-rw-r--r--libcxx/docs/Status/Cxx2cPapers.csv2
-rw-r--r--libcxx/docs/TestingLibcxx.rst2
-rw-r--r--libcxx/include/CMakeLists.txt1
-rw-r--r--libcxx/include/__configuration/availability.h38
-rw-r--r--libcxx/include/__exception/exception_ptr.h23
-rw-r--r--libcxx/include/__format/formatter_output.h62
-rw-r--r--libcxx/include/__functional/identity.h2
-rw-r--r--libcxx/include/__new/align_val_t.h6
-rw-r--r--libcxx/include/__new/exceptions.h6
-rw-r--r--libcxx/include/__type_traits/is_within_lifetime.h29
-rw-r--r--libcxx/include/deque3
-rw-r--r--libcxx/include/forward_list2
-rw-r--r--libcxx/include/list2
-rw-r--r--libcxx/include/map2
-rw-r--r--libcxx/include/module.modulemap.in1
-rw-r--r--libcxx/include/set2
-rw-r--r--libcxx/include/string33
-rw-r--r--libcxx/include/type_traits8
-rw-r--r--libcxx/include/unordered_set3
-rw-r--r--libcxx/include/version4
-rw-r--r--libcxx/modules/std/exception.inc1
-rw-r--r--libcxx/modules/std/type_traits.inc3
-rw-r--r--libcxx/test/libcxx/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp3
-rw-r--r--libcxx/test/libcxx/utilities/function.objects/lifetimebound.verify.cpp20
-rw-r--r--libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp26
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/setbuf.pass.cpp3
-rw-r--r--libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp3
-rw-r--r--libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp4
-rw-r--r--libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp1
-rw-r--r--libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_assignment.pass.cpp45
-rw-r--r--libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_ctr.pass.cpp43
-rw-r--r--libcxx/test/std/language.support/support.exception/propagation/exception_ptr_swap.pass.cpp40
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp4
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp4
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp3
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp3
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp3
-rw-r--r--libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp10
-rw-r--r--libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp148
-rw-r--r--libcxx/utils/generate_feature_test_macro_components.py3
-rw-r--r--libcxx/utils/libcxx/test/features.py34
43 files changed, 539 insertions, 100 deletions
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index dd9bf8a..d5ed918 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -478,7 +478,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_is_virtual_base_of`` ``202406L``
---------------------------------------------------------- -----------------
- ``__cpp_lib_is_within_lifetime`` *unimplemented*
+ ``__cpp_lib_is_within_lifetime`` ``202306L``
---------------------------------------------------------- -----------------
``__cpp_lib_linalg`` *unimplemented*
---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 980390c..58e0ee9 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -43,6 +43,8 @@ Implemented Papers
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
- P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)
+- P2641R4: Checking if a ``union`` alternative is active (``std::is_within_lifetime``)
+ (`Github <https://llvm.org/PR105381>`__)
- P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__)
- P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://llvm.org/PR105424>`__)
- P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index a5423ac..e0e47b8 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -18,7 +18,7 @@
"`P2874R2 <https://wg21.link/P2874R2>`__","P2874R2: Mandating Annex D Require No More","2023-06 (Varna)","|Complete|","12","`#105377 <https://github.com/llvm/llvm-project/issues/105377>`__",""
"`P2757R3 <https://wg21.link/P2757R3>`__","Type-checking format args","2023-06 (Varna)","","","`#105378 <https://github.com/llvm/llvm-project/issues/105378>`__",""
"`P2637R3 <https://wg21.link/P2637R3>`__","Member ``visit``","2023-06 (Varna)","|Complete|","19","`#105380 <https://github.com/llvm/llvm-project/issues/105380>`__","Change of ``__cpp_lib_variant`` is completed in LLVM 20. Change of ``__cpp_lib_format`` is blocked by `P2419R2 <https://wg21.link/P2419R2>`__."
-"`P2641R4 <https://wg21.link/P2641R4>`__","Checking if a ``union`` alternative is active","2023-06 (Varna)","","","`#105381 <https://github.com/llvm/llvm-project/issues/105381>`__",""
+"`P2641R4 <https://wg21.link/P2641R4>`__","Checking if a ``union`` alternative is active","2023-06 (Varna)","|Complete|","22","`#105381 <https://github.com/llvm/llvm-project/issues/105381>`__",""
"`P1759R6 <https://wg21.link/P1759R6>`__","Native handles and file streams","2023-06 (Varna)","|Complete|","18","`#105382 <https://github.com/llvm/llvm-project/issues/105382>`__",""
"`P2697R1 <https://wg21.link/P2697R1>`__","Interfacing ``bitset`` with ``string_view``","2023-06 (Varna)","|Complete|","18","`#105384 <https://github.com/llvm/llvm-project/issues/105384>`__",""
"`P1383R2 <https://wg21.link/P1383R2>`__","More ``constexpr`` for ``<cmath>`` and ``<complex>``","2023-06 (Varna)","","","`#105385 <https://github.com/llvm/llvm-project/issues/105385>`__",""
diff --git a/libcxx/docs/TestingLibcxx.rst b/libcxx/docs/TestingLibcxx.rst
index dbe6948..e15c5b1 100644
--- a/libcxx/docs/TestingLibcxx.rst
+++ b/libcxx/docs/TestingLibcxx.rst
@@ -451,7 +451,7 @@ Instead use:
.. code-block:: cpp
- // UNSUPPORTED: std-at-least-c++26
+ // REQUIRES: std-at-least-c++26
There is no corresponding ``std-at-most-c++23``. This could be useful when
tests are only valid for a small set of standard versions. For example, a
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index de9819c..57032ce 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -878,6 +878,7 @@ set(files
__type_traits/is_valid_expansion.h
__type_traits/is_void.h
__type_traits/is_volatile.h
+ __type_traits/is_within_lifetime.h
__type_traits/lazy.h
__type_traits/make_32_64_or_128_bit.h
__type_traits/make_const_lvalue_ref.h
diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index d0414ec..5433df8 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -118,14 +118,40 @@
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE __attribute__((unavailable))
// LLVM 20
-// TODO: Fill this in
-# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
-# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE __attribute__((unavailable))
+//
+// Note that versions for most Apple OSes were bumped forward and aligned in that release.
+# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 260000) || \
+ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 260000) || \
+ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 260000) || \
+ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 260000) || \
+ (defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 100000)
+# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
+# else
+# define _LIBCPP_INTRODUCED_IN_LLVM_20 1
+# endif
+# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE \
+ __attribute__((availability(macos, strict, introduced = 26.0))) \
+ __attribute__((availability(ios, strict, introduced = 26.0))) \
+ __attribute__((availability(tvos, strict, introduced = 26.0))) \
+ __attribute__((availability(watchos, strict, introduced = 26.0))) \
+ __attribute__((availability(bridgeos, strict, introduced = 10.0)))
// LLVM 19
-// TODO: Fill this in
-# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
-# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE __attribute__((unavailable))
+# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150400) || \
+ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 180400) || \
+ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 180400) || \
+ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 110400) || \
+ (defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 90400)
+# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
+# else
+# define _LIBCPP_INTRODUCED_IN_LLVM_19 1
+# endif
+# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE \
+ __attribute__((availability(macos, strict, introduced = 15.4))) \
+ __attribute__((availability(ios, strict, introduced = 18.4))) \
+ __attribute__((availability(tvos, strict, introduced = 18.4))) \
+ __attribute__((availability(watchos, strict, introduced = 11.4))) \
+ __attribute__((availability(bridgeos, strict, introduced = 9.4)))
// LLVM 18
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150000) || \
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index 796fa92..e78126e 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -16,6 +16,8 @@
#include <__memory/construct_at.h>
#include <__type_traits/decay.h>
#include <__type_traits/is_pointer.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <cstdlib>
#include <typeinfo>
@@ -23,6 +25,9 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
#ifndef _LIBCPP_ABI_MICROSOFT
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
@@ -57,6 +62,8 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
#ifndef _LIBCPP_ABI_MICROSOFT
+inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;
+
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;
@@ -75,7 +82,15 @@ public:
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
exception_ptr(const exception_ptr&) _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
+ __other.__ptr_ = nullptr;
+ }
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
+ exception_ptr __tmp(std::move(__other));
+ std::swap(__tmp, *this);
+ return *this;
+ }
~exception_ptr() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
@@ -88,10 +103,16 @@ public:
return !(__x == __y);
}
+ friend _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;
+
friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
};
+inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
+ std::swap(__x.__ptr_, __y.__ptr_);
+}
+
# if _LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
template <class _Ep>
@@ -201,4 +222,6 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
#endif // _LIBCPP_ABI_MICROSOFT
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
diff --git a/libcxx/include/__format/formatter_output.h b/libcxx/include/__format/formatter_output.h
index d53b6ce..63dd7fc 100644
--- a/libcxx/include/__format/formatter_output.h
+++ b/libcxx/include/__format/formatter_output.h
@@ -151,45 +151,41 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value)
}
}
-# if _LIBCPP_HAS_UNICODE
template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
- requires(same_as<_CharT, char>)
_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
- std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0]));
- if (__bytes == 0)
- return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
-
- for (size_t __i = 0; __i < __n; ++__i)
- __out_it = __formatter::__copy(
- std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it));
- return __out_it;
-}
-
+# if _LIBCPP_HAS_UNICODE
+ if constexpr (same_as<_CharT, char>) {
+ std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0]));
+ if (__bytes == 0)
+ return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+
+ for (size_t __i = 0; __i < __n; ++__i)
+ __out_it = __formatter::__copy(
+ std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it));
+ return __out_it;
# if _LIBCPP_HAS_WIDE_CHARACTERS
-template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
- requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
-_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
- if (!__unicode::__is_high_surrogate(__value.__data[0]))
- return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
-
- for (size_t __i = 0; __i < __n; ++__i)
- __out_it = __formatter::__copy(
- std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it));
- return __out_it;
-}
-
-template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
- requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
-_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
- return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
-}
+ } else if constexpr (same_as<_CharT, wchar_t>) {
+ if constexpr (sizeof(wchar_t) == 2) {
+ if (!__unicode::__is_high_surrogate(__value.__data[0]))
+ return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+
+ for (size_t __i = 0; __i < __n; ++__i)
+ __out_it = __formatter::__copy(
+ std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it));
+ return __out_it;
+ } else if constexpr (sizeof(wchar_t) == 4) {
+ return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+ } else {
+ static_assert(false, "expected sizeof(wchar_t) to be 2 or 4");
+ }
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-# else // _LIBCPP_HAS_UNICODE
-template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
-_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
+ } else {
+ static_assert(false, "Unexpected CharT");
+ }
+# else // _LIBCPP_HAS_UNICODE
return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+# endif // _LIBCPP_HAS_UNICODE
}
-# endif // _LIBCPP_HAS_UNICODE
/// Writes the input to the output with the required padding.
///
diff --git a/libcxx/include/__functional/identity.h b/libcxx/include/__functional/identity.h
index 1b1c6cf..02dde2b 100644
--- a/libcxx/include/__functional/identity.h
+++ b/libcxx/include/__functional/identity.h
@@ -44,7 +44,7 @@ struct __is_identity<reference_wrapper<const __identity> > : true_type {};
struct identity {
template <class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_LIBCPP_LIFETIMEBOUND _Tp&& __t) const noexcept {
return std::forward<_Tp>(__t);
}
diff --git a/libcxx/include/__new/align_val_t.h b/libcxx/include/__new/align_val_t.h
index 03ab7cb..d8ce528 100644
--- a/libcxx/include/__new/align_val_t.h
+++ b/libcxx/include/__new/align_val_t.h
@@ -16,6 +16,12 @@
# pragma GCC system_header
#endif
+// <vcruntime_exception.h> defines its own std::align_val_t type,
+// which we use in order to be ABI-compatible with other STLs on Windows.
+#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION && defined(_LIBCPP_ABI_VCRUNTIME)
+# include <vcruntime_new.h>
+#endif
+
_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION && !defined(_LIBCPP_ABI_VCRUNTIME)
# ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__new/exceptions.h b/libcxx/include/__new/exceptions.h
index 8695181..483e5e3 100644
--- a/libcxx/include/__new/exceptions.h
+++ b/libcxx/include/__new/exceptions.h
@@ -17,6 +17,12 @@
# pragma GCC system_header
#endif
+// <vcruntime_exception.h> defines its own std::bad_alloc type,
+// which we use in order to be ABI-compatible with other STLs on Windows.
+#if defined(_LIBCPP_ABI_VCRUNTIME)
+# include <vcruntime_exception.h>
+#endif
+
_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
#if !defined(_LIBCPP_ABI_VCRUNTIME)
diff --git a/libcxx/include/__type_traits/is_within_lifetime.h b/libcxx/include/__type_traits/is_within_lifetime.h
new file mode 100644
index 0000000..242f2ad
--- /dev/null
+++ b/libcxx/include/__type_traits/is_within_lifetime.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___TYPE_TRAITS_IS_WITHIN_LIFETIME_H
+#define _LIBCPP___TYPE_TRAITS_IS_WITHIN_LIFETIME_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26 && __has_builtin(__builtin_is_within_lifetime)
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI consteval bool is_within_lifetime(const _Tp* __p) noexcept {
+ return __builtin_is_within_lifetime(__p);
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_WITHIN_LIFETIME_H
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 3e7ee8d85..ab41b9d 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -193,7 +193,6 @@ template <class T, class Allocator, class Predicate>
# include <__algorithm/move_backward.h>
# include <__algorithm/remove.h>
# include <__algorithm/remove_if.h>
-# include <__algorithm/unwrap_iter.h>
# include <__assert>
# include <__config>
# include <__debug_utils/sanitizers.h>
@@ -220,11 +219,9 @@ template <class T, class Allocator, class Predicate>
# include <__ranges/concepts.h>
# include <__ranges/container_compatible_range.h>
# include <__ranges/from_range.h>
-# include <__ranges/size.h>
# include <__split_buffer>
# include <__type_traits/conditional.h>
# include <__type_traits/container_traits.h>
-# include <__type_traits/disjunction.h>
# include <__type_traits/enable_if.h>
# include <__type_traits/is_allocator.h>
# include <__type_traits/is_convertible.h>
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 88d863f..272e52d 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -223,14 +223,12 @@ template <class T, class Allocator, class Predicate>
# include <__ranges/concepts.h>
# include <__ranges/container_compatible_range.h>
# include <__ranges/from_range.h>
-# include <__type_traits/conditional.h>
# include <__type_traits/container_traits.h>
# include <__type_traits/enable_if.h>
# include <__type_traits/is_allocator.h>
# include <__type_traits/is_const.h>
# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
-# include <__type_traits/is_pointer.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
# include <__type_traits/remove_cv.h>
diff --git a/libcxx/include/list b/libcxx/include/list
index 0ff85d2..2898a45 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -228,13 +228,11 @@ template <class T, class Allocator, class Predicate>
# include <__ranges/concepts.h>
# include <__ranges/container_compatible_range.h>
# include <__ranges/from_range.h>
-# include <__type_traits/conditional.h>
# include <__type_traits/container_traits.h>
# include <__type_traits/enable_if.h>
# include <__type_traits/is_allocator.h>
# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
-# include <__type_traits/is_pointer.h>
# include <__type_traits/is_same.h>
# include <__type_traits/type_identity.h>
# include <__utility/exception_guard.h>
diff --git a/libcxx/include/map b/libcxx/include/map
index 3ff849a..cc8b876 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -600,9 +600,7 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
# include <__ranges/from_range.h>
# include <__tree>
# include <__type_traits/container_traits.h>
-# include <__type_traits/desugars_to.h>
# include <__type_traits/is_allocator.h>
-# include <__type_traits/is_convertible.h>
# include <__type_traits/make_transparent.h>
# include <__type_traits/remove_const.h>
# include <__type_traits/type_identity.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 11ab61d..24a2fe7 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -350,6 +350,7 @@ module std_core [system] {
header "__type_traits/is_volatile.h"
export std_core.type_traits.integral_constant
}
+ module is_within_lifetime { header "__type_traits/is_within_lifetime.h" }
module lazy { header "__type_traits/lazy.h" }
module make_32_64_or_128_bit { header "__type_traits/make_32_64_or_128_bit.h" }
module make_const_lvalue_ref { header "__type_traits/make_const_lvalue_ref.h" }
diff --git a/libcxx/include/set b/libcxx/include/set
index 59ed015..d58b6e9 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -524,7 +524,6 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
# include <__functional/operations.h>
# include <__iterator/erase_if_container.h>
# include <__iterator/iterator_traits.h>
-# include <__iterator/ranges_iterator_traits.h>
# include <__iterator/reverse_iterator.h>
# include <__memory/allocator.h>
# include <__memory/allocator_traits.h>
@@ -538,7 +537,6 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
# include <__type_traits/container_traits.h>
# include <__type_traits/enable_if.h>
# include <__type_traits/is_allocator.h>
-# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
diff --git a/libcxx/include/string b/libcxx/include/string
index 8f80afbc..ede4246 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -644,6 +644,7 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
# include <__utility/forward.h>
# include <__utility/is_pointer_in_range.h>
# include <__utility/move.h>
+# include <__utility/no_destroy.h>
# include <__utility/scope_guard.h>
# include <__utility/swap.h>
# include <climits>
@@ -914,6 +915,11 @@ private:
union __rep {
__short __s;
__long __l;
+
+ __rep() = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__short __r) : __s(__r) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __l(__r) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__uninitialized_tag) {}
};
_LIBCPP_COMPRESSED_PAIR(__rep, __rep_, allocator_type, __alloc_);
@@ -1206,7 +1212,10 @@ public:
}
# endif // _LIBCPP_CXX03_LANG
- inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() { __reset_internal_buffer(); }
+ // TODO(boomanaiden154): Once we mark this in destructors as dead on return,
+ // we can use a normal call to __reset_internal_buffer and remove the extra
+ // __rep constructor.
+ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() { __reset_internal_buffer(__rep(__uninitialized_tag())); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator __self_view() const _NOEXCEPT {
return __self_view(typename __self_view::__assume_valid(), data(), size());
@@ -2259,18 +2268,12 @@ private:
return __long(__buffer, __capacity);
}
- // Deallocate the long buffer if it exists and clear the short buffer so we are an empty string
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reset_internal_buffer() {
+ // Replace the current buffer with __new_rep. Deallocate the old long buffer if it exists.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reset_internal_buffer(__rep __new_rep = __short()) {
__annotate_delete();
if (__is_long())
__alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
- __rep_.__s = __short();
- }
-
- // Replace the current buffer with __alloc; the first __size elements constitute a string
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __replace_internal_buffer(__long __alloc) {
- __reset_internal_buffer();
- __rep_.__l = __alloc;
+ __rep_ = __new_rep;
}
// Initialize the internal buffer to hold __size elements
@@ -2444,7 +2447,7 @@ private:
__annotate_delete();
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
auto __alloc = __str.__alloc_;
- __replace_internal_buffer(__allocate_long_buffer(__alloc, __str.size()));
+ __reset_internal_buffer(__allocate_long_buffer(__alloc, __str.size()));
__alloc_ = std::move(__alloc);
}
}
@@ -2710,7 +2713,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
__sec_cp_sz);
__buffer.__size_ = __n_copy + __n_add + __sec_cp_sz;
traits_type::assign(__buffer.__data_[__buffer.__size_], value_type());
- __replace_internal_buffer(__buffer);
+ __reset_internal_buffer(__buffer);
}
// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
@@ -2746,7 +2749,7 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
// This is -1 to make sure the caller sets the size properly, since old versions of this function didn't set the size
// at all.
__buffer.__size_ = -1;
- __replace_internal_buffer(__buffer);
+ __reset_internal_buffer(__buffer);
}
template <class _CharT, class _Traits, class _Allocator>
@@ -3394,7 +3397,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
__long __buffer = __allocate_long_buffer(__alloc_, __requested_capacity);
__buffer.__size_ = size();
traits_type::copy(std::__to_address(__buffer.__data_), data(), __buffer.__size_ + 1);
- __replace_internal_buffer(__buffer);
+ __reset_internal_buffer(__buffer);
}
template <class _CharT, class _Traits, class _Allocator>
@@ -3433,7 +3436,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
}
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__get_long_pointer()), __size + 1);
- __replace_internal_buffer(__buffer);
+ __reset_internal_buffer(__buffer);
# if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
return;
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index a6e0c18..dab0c06 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -454,6 +454,10 @@ namespace std
template<class B> inline constexpr bool negation_v
= negation<B>::value; // since C++17
+ // [meta.const.eval], constant evaluation context
+ constexpr bool is_constant_evaluated() noexcept; // C++20
+ template<class T>
+ consteval bool is_within_lifetime(const T*) noexcept; // C++26
}
*/
@@ -559,6 +563,10 @@ namespace std
# include <__type_traits/reference_converts_from_temporary.h>
# endif
+# if _LIBCPP_STD_VER >= 26
+# include <__type_traits/is_within_lifetime.h>
+# endif
+
# include <version>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 4d0e2ac..9873f1e 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -544,8 +544,6 @@ template <class Value, class Hash, class Pred, class Alloc>
# include <__iterator/distance.h>
# include <__iterator/erase_if_container.h>
# include <__iterator/iterator_traits.h>
-# include <__iterator/ranges_iterator_traits.h>
-# include <__memory/addressof.h>
# include <__memory/allocator.h>
# include <__memory/allocator_traits.h>
# include <__memory_resource/polymorphic_allocator.h>
@@ -558,7 +556,6 @@ template <class Value, class Hash, class Pred, class Alloc>
# include <__type_traits/invoke.h>
# include <__type_traits/is_allocator.h>
# include <__type_traits/is_integral.h>
-# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
diff --git a/libcxx/include/version b/libcxx/include/version
index b41cc9e..b003060 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -586,7 +586,9 @@ __cpp_lib_void_t 201411L <type_traits>
# if __has_builtin(__builtin_is_virtual_base_of)
# define __cpp_lib_is_virtual_base_of 202406L
# endif
-// # define __cpp_lib_is_within_lifetime 202306L
+# if __has_builtin(__builtin_is_within_lifetime)
+# define __cpp_lib_is_within_lifetime 202306L
+# endif
// # define __cpp_lib_linalg 202311L
# undef __cpp_lib_mdspan
# define __cpp_lib_mdspan 202406L
diff --git a/libcxx/modules/std/exception.inc b/libcxx/modules/std/exception.inc
index 02b0f80..3dbc011 100644
--- a/libcxx/modules/std/exception.inc
+++ b/libcxx/modules/std/exception.inc
@@ -18,6 +18,7 @@ export namespace std {
using std::rethrow_exception;
using std::rethrow_if_nested;
using std::set_terminate;
+ using std::swap;
using std::terminate;
using std::terminate_handler;
using std::throw_with_nested;
diff --git a/libcxx/modules/std/type_traits.inc b/libcxx/modules/std/type_traits.inc
index 6823c86..4e49ed8 100644
--- a/libcxx/modules/std/type_traits.inc
+++ b/libcxx/modules/std/type_traits.inc
@@ -330,6 +330,9 @@ export namespace std {
// [meta.const.eval], constant evaluation context
using std::is_constant_evaluated;
+#if _LIBCPP_STD_VER >= 26 && __has_builtin(__builtin_is_within_lifetime)
+ using std::is_within_lifetime;
+#endif
// [depr.meta.types]
using std::aligned_storage;
diff --git a/libcxx/test/libcxx/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp b/libcxx/test/libcxx/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp
index 16d66e3..e5d48a3 100644
--- a/libcxx/test/libcxx/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp
+++ b/libcxx/test/libcxx/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp
@@ -10,8 +10,7 @@
// The fix for issue 57964 requires an updated dylib due to explicit
// instantiations. That means Apple backdeployment targets remain broken.
-// TODO: Remove && !darwin once availability markup for LLVM 19 on macOS has been added
-// XFAIL: using-built-library-before-llvm-19 && !darwin
+// XFAIL: using-built-library-before-llvm-19
// <ios>
diff --git a/libcxx/test/libcxx/utilities/function.objects/lifetimebound.verify.cpp b/libcxx/test/libcxx/utilities/function.objects/lifetimebound.verify.cpp
new file mode 100644
index 0000000..5c66bc1
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/function.objects/lifetimebound.verify.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// ADDITIONAL_COMPILE_FLAGS: -Wno-pessimizing-move -Wno-unused-variable
+
+#include <functional>
+
+#include "test_macros.h"
+
+// clang-format off
+
+void func() {
+ auto&& v1 = std::identity()(1); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+}
diff --git a/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp b/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp
new file mode 100644
index 0000000..ff3ecfb
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// UNSUPPORTED: gcc-15, apple-clang-17
+
+// <type_traits>
+
+// LWG4138 <https://cplusplus.github.io/LWG/issue4138>
+// std::is_within_lifetime shouldn't work when a function type is
+// explicitly specified, even if it isn't evaluated
+
+#include <type_traits>
+
+template <class T>
+consteval bool checked_is_within_lifetime(T* p) {
+ return p ? std::is_within_lifetime<T>(p) : false;
+}
+static_assert(!checked_is_within_lifetime<int>(nullptr));
+static_assert(!checked_is_within_lifetime<void()>(nullptr));
+// expected-error@*:* {{function pointer argument to '__builtin_is_within_lifetime' is not allowed}}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/setbuf.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/setbuf.pass.cpp
index 00aa97a..72af0a2 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/setbuf.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/setbuf.pass.cpp
@@ -12,8 +12,7 @@
// This test requires the fix to https://llvm.org/PR60509 in the dylib,
// which landed in 5afb937d8a30445642ccaf33866ee4cdd0713222.
-// TODO: Remove && !darwin once availability markup for LLVM 19 on macOS has been added
-// XFAIL: using-built-library-before-llvm-19 && !darwin
+// XFAIL: using-built-library-before-llvm-19
#include <fstream>
#include <cstddef>
diff --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
index b04d2c0..79d20ce 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
@@ -13,8 +13,7 @@
// The fix for bug 51497 and bug 51499 require and updated dylib due to
// explicit instantiations. That means Apple backdeployment targets remain
// broken.
-// TODO: Remove && !darwin once availability markup for LLVM 19 on macOS has been added
-// XFAIL: using-built-library-before-llvm-19 && !darwin
+// XFAIL: using-built-library-before-llvm-19
#include <istream>
#include <cassert>
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
index 665a1a8..a238b75 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
@@ -17,10 +17,10 @@
// LWG 198 was superseded by LWG 2360
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2360
-
+#include <cassert>
#include <iterator>
#include <list>
-#include <cassert>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp
index 0aded33..7e25d40 100644
--- a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp
+++ b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp
@@ -14,7 +14,6 @@
#include <exception>
#include <cassert>
-#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_assignment.pass.cpp b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_assignment.pass.cpp
new file mode 100644
index 0000000..6882bc6
--- /dev/null
+++ b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_assignment.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions, c++03
+
+// <exception>
+
+// typedef unspecified exception_ptr;
+
+// Test the move assignment of exception_ptr
+
+#include <exception>
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::exception_ptr p = std::make_exception_ptr(42);
+ std::exception_ptr p2{p};
+ assert(p2 == p);
+ // Under test: the move assignment
+ std::exception_ptr p3;
+ p3 = std::move(p2);
+ assert(p3 == p);
+// `p2` was moved from. In libc++ it will be nullptr, but
+// this is not guaranteed by the standard.
+#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_ABI_MICROSOFT)
+ assert(p2 == nullptr);
+ assert(p2 == nullptr);
+#endif
+
+ try {
+ std::rethrow_exception(p3);
+ } catch (int e) {
+ assert(e == 42);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_ctr.pass.cpp b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_ctr.pass.cpp
new file mode 100644
index 0000000..122e229
--- /dev/null
+++ b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_move_ctr.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions, c++03
+
+// <exception>
+
+// typedef unspecified exception_ptr;
+
+// Test the move constructor of exception_ptr
+
+#include <exception>
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::exception_ptr p = std::make_exception_ptr(42);
+ std::exception_ptr p2{p};
+ assert(p2 == p);
+ // Under test: The move constructor
+ std::exception_ptr p3{std::move(p2)};
+ assert(p3 == p);
+// `p2` was moved from. In libc++ it will be nullptr, but
+// this is not guaranteed by the standard.
+#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_ABI_MICROSOFT)
+ assert(p2 == nullptr);
+#endif
+
+ try {
+ std::rethrow_exception(p3);
+ } catch (int e) {
+ assert(e == 42);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_swap.pass.cpp b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_swap.pass.cpp
new file mode 100644
index 0000000..82b4713
--- /dev/null
+++ b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr_swap.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// <exception>
+
+// typedef unspecified exception_ptr;
+
+// Test swapping of exception_ptr
+
+#include <exception>
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::exception_ptr p21 = std::make_exception_ptr(42);
+ std::exception_ptr p42 = std::make_exception_ptr(21);
+ std::swap(p42, p21);
+
+ try {
+ std::rethrow_exception(p21);
+ } catch (int e) {
+ assert(e == 21);
+ }
+ try {
+ std::rethrow_exception(p42);
+ } catch (int e) {
+ assert(e == 42);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp
index 0074f3b..cb5c008 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp
@@ -918,7 +918,7 @@
# endif
# endif
-# if !defined(_LIBCPP_VERSION)
+# if __has_builtin(__builtin_is_within_lifetime)
# ifndef __cpp_lib_is_within_lifetime
# error "__cpp_lib_is_within_lifetime should be defined in c++26"
# endif
@@ -927,7 +927,7 @@
# endif
# else
# ifdef __cpp_lib_is_within_lifetime
-# error "__cpp_lib_is_within_lifetime should not be defined because it is unimplemented in libc++!"
+# error "__cpp_lib_is_within_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_within_lifetime)' is not met!"
# endif
# endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index a9552c2..8189c5c 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -7310,7 +7310,7 @@
# endif
# endif
-# if !defined(_LIBCPP_VERSION)
+# if __has_builtin(__builtin_is_within_lifetime)
# ifndef __cpp_lib_is_within_lifetime
# error "__cpp_lib_is_within_lifetime should be defined in c++26"
# endif
@@ -7319,7 +7319,7 @@
# endif
# else
# ifdef __cpp_lib_is_within_lifetime
-# error "__cpp_lib_is_within_lifetime should not be defined because it is unimplemented in libc++!"
+# error "__cpp_lib_is_within_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_within_lifetime)' is not met!"
# endif
# endif
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
index 31682fea..a388c0b 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
@@ -8,8 +8,7 @@
// The fix for LWG2381 (https://github.com/llvm/llvm-project/pull/77948) changed behavior of
// FP parsing. This requires 3e15c97fa3812993bdc319827a5c6d867b765ae8 in the dylib.
-// TODO: Remove && !darwin once availability markup for LLVM 19 on macOS has been added
-// XFAIL: using-built-library-before-llvm-19 && !darwin
+// XFAIL: using-built-library-before-llvm-19
// <locale>
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
index 57eedc8..596d81c 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
@@ -8,8 +8,7 @@
// The fix for LWG2381 (https://github.com/llvm/llvm-project/pull/77948) changed behavior of
// FP parsing. This requires 3e15c97fa3812993bdc319827a5c6d867b765ae8 in the dylib.
-// TODO: Remove && !darwin once availability markup for LLVM 19 on macOS has been added
-// XFAIL: using-built-library-before-llvm-19 && !darwin
+// XFAIL: using-built-library-before-llvm-19
// <locale>
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
index 8324ee3..8a9fd41 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
@@ -8,8 +8,7 @@
// The fix for LWG2381 (https://github.com/llvm/llvm-project/pull/77948) changed behavior of
// FP parsing. This requires 3e15c97fa3812993bdc319827a5c6d867b765ae8 in the dylib.
-// TODO: Remove && !darwin once availability markup for LLVM 19 on macOS has been added
-// XFAIL: using-built-library-before-llvm-19 && !darwin
+// XFAIL: using-built-library-before-llvm-19
// <locale>
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
index 5eb3240..8e59195 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
@@ -8,11 +8,13 @@
// UNSUPPORTED: no-exceptions
-// After changing the alignment of the allocated pointer from 16 to 8, the exception
-// thrown is no longer `bad_alloc` but instead length_error on systems using new
-// headers but a dylib that doesn't contain 04ce0ba.
+// This test fails when using a built library that does not contain
+// 15860446a8c3, which changed the return value of max_size(). Without
+// that change, the built library believes the max size to be one greater
+// than it really is, and we fail to throw `length_error` from `string::resize()`,
+// which is explicitly instantiated in the built library.
//
-// XFAIL: using-built-library-before-llvm-19
+// XFAIL: using-built-library-before-llvm-21
// <string>
diff --git a/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp
new file mode 100644
index 0000000..40c2273
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// UNSUPPORTED: gcc-15, apple-clang-17
+
+// <type_traits>
+
+// template <class T>
+// consteval bool is_within_lifetime(const T*) noexcept; // C++26
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<int*>())), bool);
+ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<const int*>())), bool);
+ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<void*>())), bool);
+ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<const void*>())), bool);
+
+ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<int*>()));
+ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<const int*>()));
+ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<void*>()));
+ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<const void*>()));
+
+template <class T>
+concept is_within_lifetime_exists = requires(T t) { std::is_within_lifetime(t); };
+
+struct S {};
+
+static_assert(is_within_lifetime_exists<int*>);
+static_assert(is_within_lifetime_exists<const int*>);
+static_assert(is_within_lifetime_exists<void*>);
+static_assert(is_within_lifetime_exists<const void*>);
+static_assert(!is_within_lifetime_exists<int>); // Not a pointer
+static_assert(!is_within_lifetime_exists<decltype(nullptr)>); // Not a pointer
+static_assert(!is_within_lifetime_exists<void() const>); // Not a pointer
+static_assert(!is_within_lifetime_exists<int S::*>); // Doesn't accept pointer-to-data-member
+static_assert(!is_within_lifetime_exists<void (S::*)()>); // Doesn't accept pointer-to-member-function
+static_assert(!is_within_lifetime_exists<void (*)()>); // Doesn't match `const T*`
+
+consteval bool f() {
+ // Test that it works with global variables whose lifetime is in a
+ // different constant expression
+ {
+ static constexpr int i = 0;
+ static_assert(std::is_within_lifetime(&i));
+ // (Even when cast to a different type)
+ static_assert(std::is_within_lifetime(const_cast<int*>(&i)));
+ static_assert(std::is_within_lifetime(static_cast<const void*>(&i)));
+ static_assert(std::is_within_lifetime(static_cast<void*>(const_cast<int*>(&i))));
+ static_assert(std::is_within_lifetime<const int>(&i));
+ static_assert(std::is_within_lifetime<int>(const_cast<int*>(&i)));
+ static_assert(std::is_within_lifetime<const void>(static_cast<const void*>(&i)));
+ static_assert(std::is_within_lifetime<void>(static_cast<void*>(const_cast<int*>(&i))));
+ }
+
+ {
+ static constexpr union {
+ int member1;
+ int member2;
+ } u{.member2 = 1};
+ static_assert(!std::is_within_lifetime(&u.member1) && std::is_within_lifetime(&u.member2));
+ }
+
+ // Test that it works for varibles inside the same constant expression
+ {
+ int i = 0;
+ assert(std::is_within_lifetime(&i));
+ // (Even when cast to a different type)
+ assert(std::is_within_lifetime(const_cast<int*>(&i)));
+ assert(std::is_within_lifetime(static_cast<const void*>(&i)));
+ assert(std::is_within_lifetime(static_cast<void*>(const_cast<int*>(&i))));
+ assert(std::is_within_lifetime<const int>(&i));
+ assert(std::is_within_lifetime<int>(const_cast<int*>(&i)));
+ assert(std::is_within_lifetime<const void>(static_cast<const void*>(&i)));
+ assert(std::is_within_lifetime<void>(static_cast<void*>(const_cast<int*>(&i))));
+ }
+ // Anonymous union
+ {
+ union {
+ int member1;
+ int member2;
+ };
+ assert(!std::is_within_lifetime(&member1) && !std::is_within_lifetime(&member2));
+ member1 = 1;
+ assert(std::is_within_lifetime(&member1) && !std::is_within_lifetime(&member2));
+ member2 = 1;
+ assert(!std::is_within_lifetime(&member1) && std::is_within_lifetime(&member2));
+ }
+ // Variant members
+ {
+ struct X {
+ union {
+ int member1;
+ int member2;
+ };
+ } x;
+ assert(!std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));
+ x.member1 = 1;
+ assert(std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));
+ x.member2 = 1;
+ assert(!std::is_within_lifetime(&x.member1) && std::is_within_lifetime(&x.member2));
+ }
+ // Unions
+ {
+ union X {
+ int member1;
+ int member2;
+ } x;
+ assert(!std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));
+ x.member1 = 1;
+ assert(std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));
+ x.member2 = 1;
+ assert(!std::is_within_lifetime(&x.member1) && std::is_within_lifetime(&x.member2));
+ }
+ {
+ S s; // uninitialised
+ assert(std::is_within_lifetime(&s));
+ }
+
+ return true;
+}
+static_assert(f());
+
+// Check that it is a consteval (and consteval-propagating) function
+// (i.e., taking the address of below will fail because it will be an immediate function)
+template <typename T>
+constexpr void does_escalate(T p) {
+ std::is_within_lifetime(p);
+}
+template <typename T, void (*)(T) = &does_escalate<T>>
+constexpr bool check_escalated(int) {
+ return false;
+}
+template <typename T>
+constexpr bool check_escalated(long) {
+ return true;
+}
+static_assert(check_escalated<int*>(0), "");
+static_assert(check_escalated<void*>(0), "");
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 3d39130..22209f5 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -873,7 +873,8 @@ feature_test_macros = [
"c++26": 202306 # P2641R4 Checking if a union alternative is active
},
"headers": ["type_traits"],
- "unimplemented": True,
+ "test_suite_guard": "__has_builtin(__builtin_is_within_lifetime)",
+ "libcxx_guard": "__has_builtin(__builtin_is_within_lifetime)",
},
{
"name": "__cpp_lib_jthread",
diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 7d6e78d..5da1d9a 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -734,16 +734,44 @@ DEFAULT_FEATURES += [
# Those are used for backdeployment features below, do not use directly in tests.
DEFAULT_FEATURES += [
Feature(
+ name="_target-has-llvm-22",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "TBD",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-21",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "TBD",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-20",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-21 || target={{.+}}-apple-macosx{{26.[0-9](.\d+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-19",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-20 || target={{.+}}-apple-macosx{{15.[4-9](.\d+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
name="_target-has-llvm-18",
when=lambda cfg: BooleanExpression.evaluate(
- "target={{.+}}-apple-macosx{{15(.[0-9]+)?(.[0-9]+)?}}",
+ "_target-has-llvm-19 || target={{.+}}-apple-macosx{{15.[0-3](.\d+)?}}",
cfg.available_features,
),
),
Feature(
name="_target-has-llvm-17",
when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.[0-9]+)?}} || target={{.+}}-apple-macosx{{1[5-9]([.].+)?}}",
+ "_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.\d+)?}}",
cfg.available_features,
),
),
@@ -821,7 +849,7 @@ DEFAULT_FEATURES += [
# a libc++ flavor that enables availability markup. Similarly, a test could fail when
# run against the system library of an older version of FreeBSD, even though FreeBSD
# doesn't provide availability markup at the time of writing this.
-for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20"):
+for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"):
DEFAULT_FEATURES.append(
Feature(
name="using-built-library-before-llvm-{}".format(version),