diff options
Diffstat (limited to 'libcxx')
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),  | 
