From f7ff07eca878d623777ab440e1f82dd93e273826 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 Jul 2024 14:02:52 +0800 Subject: [PATCH 01/20] [libc++] Remove functions deprecated in C++17 and removed in C++20 Works towards P0619R4. - `std::uncaught_exception` was not previously deprecated. This patch deprecates it since C++17 as per N4259. `std::uncaught_exceptions` is used instead as libc++ unconditionally provides this function. - `std::get_temporary_buffer` is replaced with the internal version `__get_temporary_buffer`. - `std::return_temporary_buffer` is replaced with direct `__libcpp_deallocate_unsized` call. Escape hatches: - `_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION` restores `std::uncaught_exception`. - `_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER` restores `std::get_temporary_buffer` and `std::return_temporary_buffer`. --- libcxx/docs/Status/Cxx17.rst | 1 + libcxx/docs/Status/Cxx17Papers.csv | 2 +- libcxx/docs/Status/Cxx20.rst | 2 +- libcxx/docs/UsingLibcxx.rst | 6 ++++ libcxx/include/__algorithm/inplace_merge.h | 5 +--- libcxx/include/__algorithm/stable_partition.h | 10 ++----- libcxx/include/__algorithm/stable_sort.h | 5 +--- libcxx/include/__exception/operations.h | 4 ++- libcxx/include/__memory/temporary_buffer.h | 28 ++++++++++++------- libcxx/include/__ostream/basic_ostream.h | 2 +- libcxx/include/exception | 2 +- libcxx/include/memory | 4 +-- libcxx/include/syncstream | 2 +- libcxx/modules/std/exception.inc | 1 - libcxx/src/exception.cpp | 3 ++ .../diagnostics/memory.nodiscard.verify.cpp | 1 + .../alg.partitions/stable_partition.pass.cpp | 6 ++-- .../uncaught/uncaught_exception.pass.cpp | 4 +++ .../temporary.buffer/overaligned.pass.cpp | 1 + .../temporary_buffer.pass.cpp | 1 + libcxx/utils/libcxx/test/modules.py | 7 ----- 21 files changed, 52 insertions(+), 45 deletions(-) diff --git a/libcxx/docs/Status/Cxx17.rst b/libcxx/docs/Status/Cxx17.rst index ad4f8576f03db..ac07d299d7e74 100644 --- a/libcxx/docs/Status/Cxx17.rst +++ b/libcxx/docs/Status/Cxx17.rst @@ -40,6 +40,7 @@ Paper Status .. note:: + .. [#note-N4259] N4259: ``std::uncaught_exception`` is deprecated since version 20.0. .. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``. .. [#note-P0226] P0226: Progress is tracked `here `_. .. [#note-P0607] P0607: The parts of P0607 that are not done are the ```` bits. diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv index 6c657d51f5c7e..f9a87b2cbfd22 100644 --- a/libcxx/docs/Status/Cxx17Papers.csv +++ b/libcxx/docs/Status/Cxx17Papers.csv @@ -4,7 +4,7 @@ "`N4169 `__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7" "`N4190 `__","LWG","Removing auto_ptr, random_shuffle(), And Old Stuff.","Urbana","|Complete|","15.0" "`N4258 `__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7" -"`N4259 `__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7" +"`N4259 `__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete| [#note-N4259]_","3.7" "`N4277 `__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2" "`N4279 `__","LWG","Improved insertion interface for unique-key maps.","Urbana","|Complete|","3.7" "`N4280 `__","LWG","Non-member size() and more","Urbana","|Complete|","3.6" diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst index b76e30fbb3712..a13496bd0a8fd 100644 --- a/libcxx/docs/Status/Cxx20.rst +++ b/libcxx/docs/Status/Cxx20.rst @@ -44,7 +44,7 @@ Paper Status .. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature (the feature-test macro is not set). .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 `__. - .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, and D.12 remain undone. + .. [#note-P0619] P0619: Section D.4 remains undone. .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0. .. [#note-P0660] P0660: The paper is implemented but the features are experimental and can be enabled via ``-fexperimental-library``. diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst index df08875c13bea..8937639bd2bf2 100644 --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -215,6 +215,9 @@ C++17 Specific Configuration Macros C++20 Specific Configuration Macros ----------------------------------- +**_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION**: + This macro is used to re-enable `uncaught_exception`. + **_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**: This macro is used to re-enable the function ``std::shared_ptr<...>::unique()``. @@ -231,6 +234,9 @@ C++20 Specific Configuration Macros **_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR**: This macro is used to re-enable `raw_storage_iterator`. +**_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER**: + This macro is used to re-enable `get_temporary_buffer` and `return_temporary_buffer`. + **_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS**: This macro is used to re-enable `is_literal_type`, `is_literal_type_v`, `result_of` and `result_of_t`. diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index a6bcc66a2fa47..4c6ab527c8188 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -211,10 +211,7 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = std::min(__len1, __len2); - // TODO: Remove the use of std::get_temporary_buffer - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - pair __buf = std::get_temporary_buffer(__buf_size); - _LIBCPP_SUPPRESS_DEPRECATED_POP + pair __buf = std::__get_temporary_buffer(__buf_size); unique_ptr __h(__buf.first); return std::__inplace_merge<_AlgPolicy>( std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 8bb1eaf2d2249..4f09b87ae0f9a 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -135,10 +135,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred pair __p(0, 0); unique_ptr __h; if (__len >= __alloc_limit) { - // TODO: Remove the use of std::get_temporary_buffer - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - __p = std::get_temporary_buffer(__len); - _LIBCPP_SUPPRESS_DEPRECATED_POP + __p = std::__get_temporary_buffer(__len); __h.reset(__p.first); } return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( @@ -275,10 +272,7 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( pair __p(0, 0); unique_ptr __h; if (__len >= __alloc_limit) { - // TODO: Remove the use of std::get_temporary_buffer - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - __p = std::get_temporary_buffer(__len); - _LIBCPP_SUPPRESS_DEPRECATED_POP + __p = std::__get_temporary_buffer(__len); __h.reset(__p.first); } return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 726e7e16b3564..69fd85cc798bd 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -244,10 +244,7 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, pair __buf(0, 0); unique_ptr __h; if (__len > static_cast(__stable_sort_switch::value)) { - // TODO: Remove the use of std::get_temporary_buffer - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - __buf = std::get_temporary_buffer(__len); - _LIBCPP_SUPPRESS_DEPRECATED_POP + __buf = std::__get_temporary_buffer(__len); __h.reset(__buf.first); } diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h index 0a9c7a7c7f0d8..4a0a697c00e6e 100644 --- a/libcxx/include/__exception/operations.h +++ b/libcxx/include/__exception/operations.h @@ -29,7 +29,9 @@ using terminate_handler = void (*)(); _LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT; -_LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION) +_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT; +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION) _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT; class _LIBCPP_EXPORTED_FROM_ABI exception_ptr; diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index 88799ca95c1f3..c6cb338905184 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -22,8 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> -get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { pair<_Tp*, ptrdiff_t> __r(0, 0); const ptrdiff_t __m = (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp); @@ -56,20 +56,28 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { return __r; } -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); -} - struct __return_temporary_buffer { - _LIBCPP_SUPPRESS_DEPRECATED_PUSH template _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) const { - std::return_temporary_buffer(__p); + std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); } - _LIBCPP_SUPPRESS_DEPRECATED_POP }; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> +get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { + return std::__get_temporary_buffer<_Tp>(__n); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { + std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); +} + +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h index 178359d681567..e0698ccb4842a 100644 --- a/libcxx/include/__ostream/basic_ostream.h +++ b/libcxx/include/__ostream/basic_ostream.h @@ -152,7 +152,7 @@ basic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& _ template basic_ostream<_CharT, _Traits>::sentry::~sentry() { - if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && !uncaught_exception()) { + if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) { #ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS diff --git a/libcxx/include/exception b/libcxx/include/exception index 5eff8e3f8a4bf..64463e02cb16a 100644 --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -47,7 +47,7 @@ terminate_handler set_terminate(terminate_handler f ) noexcept; terminate_handler get_terminate() noexcept; [[noreturn]] void terminate() noexcept; -bool uncaught_exception() noexcept; +bool uncaught_exception() noexcept; // deprecated in C++17, removed in C++20 int uncaught_exceptions() noexcept; // C++17 typedef unspecified exception_ptr; diff --git a/libcxx/include/memory b/libcxx/include/memory index b940a32c3ebe6..db3386cca4800 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -182,8 +182,8 @@ public: raw_storage_iterator operator++(int); }; -template pair get_temporary_buffer(ptrdiff_t n) noexcept; -template void return_temporary_buffer(T* p) noexcept; +template pair get_temporary_buffer(ptrdiff_t n) noexcept; // deprecated in C++17, removed in C++20 +template void return_temporary_buffer(T* p) noexcept; // deprecated in C++17, removed in C++20 template T* addressof(T& r) noexcept; template T* addressof(const T&& r) noexcept = delete; diff --git a/libcxx/include/syncstream b/libcxx/include/syncstream index e6f35b6f428ed..9da2abb252bfd 100644 --- a/libcxx/include/syncstream +++ b/libcxx/include/syncstream @@ -358,7 +358,7 @@ private: // TODO Use a more generic buffer. // That buffer should be light with almost no additional headers. Then // it can be use here, the __retarget_buffer, and place that use - // the now deprecated get_temporary_buffer + // the now removed get_temporary_buffer basic_string<_CharT, _Traits, _Allocator> __str_; bool __emit_on_sync_{false}; diff --git a/libcxx/modules/std/exception.inc b/libcxx/modules/std/exception.inc index 8e802c7065e0f..0c110e6e743fb 100644 --- a/libcxx/modules/std/exception.inc +++ b/libcxx/modules/std/exception.inc @@ -21,6 +21,5 @@ export namespace std { using std::terminate; using std::terminate_handler; using std::throw_with_nested; - using std::uncaught_exception; using std::uncaught_exceptions; } // namespace std diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp index ddb186bf8048f..ac6324cd9fe35 100644 --- a/libcxx/src/exception.cpp +++ b/libcxx/src/exception.cpp @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION +#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS + #include #include #include diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp index 646569e3d573a..6410c84e926aa 100644 --- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp @@ -10,6 +10,7 @@ // check that functions are marked [[nodiscard]] +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS // clang-format off diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp index 85d12d08c9675..44027543aaf16 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp @@ -282,9 +282,9 @@ test() assert(array[9] == P(0, 2)); } #if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) - // TODO: Re-enable this test once we're no longer using get_temporary_buffer(). + // TODO: Re-enable this test once we get recursive inlining fixed. // For now it trips up GCC due to the use of always_inline. -#if 0 +# if 0 { // check that the algorithm still works when no memory is available std::vector vec(150, 3); vec[5] = 6; @@ -300,7 +300,7 @@ test() assert(std::is_partitioned(vec.begin(), vec.end(), [](int i) { return i < 5; })); getGlobalMemCounter()->reset(); } -#endif +# endif #endif // TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) } diff --git a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp index e368ce177b317..6fa4cb22070c8 100644 --- a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp +++ b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp @@ -7,6 +7,10 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-exceptions + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // test uncaught_exception #include diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp index 8499478d1fb38..4c66370fac922 100644 --- a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp +++ b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp @@ -8,6 +8,7 @@ // UNSUPPORTED: c++03 +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS // diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp index 6c0fbf2568fff..5f7fc4571906c 100644 --- a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp +++ b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp @@ -8,6 +8,7 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS // template diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py index b7758dc9a41ee..ed0e0d684327b 100644 --- a/libcxx/utils/libcxx/test/modules.py +++ b/libcxx/utils/libcxx/test/modules.py @@ -52,13 +52,6 @@ "std::operator==", ] -# TODO MODULES remove zombie names -# https://libcxx.llvm.org/Status/Cxx20.html#note-p0619 -SkipDeclarations["memory"] = [ - "std::return_temporary_buffer", - "std::get_temporary_buffer", -] - # include/__type_traits/is_swappable.h SkipDeclarations["type_traits"] = [ "std::swap", From 25a978279fdf90f99dae1f823b3b6ac3624ac6f0 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 1 Aug 2024 22:33:41 +0800 Subject: [PATCH 02/20] Document escape hatches to 20.rst --- libcxx/docs/ReleaseNotes/20.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index f959c8829277e..db318525f4b5f 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -44,6 +44,12 @@ Implemented Papers Improvements and New Features ----------------------------- +- The ``_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION`` macro has been added to make ``std::uncaught_exception`` + available. + +- The ``_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER`` macro has been added to make ``std::get_temporary_buffer`` and + ``std::return_temporary_buffer`` available. + - TODO From 60212b2e95da50f21e20ffc402a0b259add89f39 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 3 Aug 2024 23:19:17 +0800 Subject: [PATCH 03/20] Split changes for `uncaught_exception` to another PR --- libcxx/docs/ReleaseNotes/20.rst | 3 --- libcxx/docs/Status/Cxx17.rst | 1 - libcxx/docs/Status/Cxx20.rst | 2 +- libcxx/docs/UsingLibcxx.rst | 3 --- libcxx/include/__exception/operations.h | 4 +--- libcxx/include/__ostream/basic_ostream.h | 2 +- libcxx/modules/std/exception.inc | 1 + libcxx/src/exception.cpp | 3 --- 8 files changed, 4 insertions(+), 15 deletions(-) diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index f6b5b3e9623d4..b24b65270e3c7 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -44,9 +44,6 @@ Implemented Papers Improvements and New Features ----------------------------- -- The ``_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION`` macro has been added to make ``std::uncaught_exception`` - available. - - The ``_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER`` macro has been added to make ``std::get_temporary_buffer`` and ``std::return_temporary_buffer`` available. diff --git a/libcxx/docs/Status/Cxx17.rst b/libcxx/docs/Status/Cxx17.rst index 6bccd4cf854c4..3f1f2071300c8 100644 --- a/libcxx/docs/Status/Cxx17.rst +++ b/libcxx/docs/Status/Cxx17.rst @@ -40,7 +40,6 @@ Paper Status .. note:: - .. [#note-N4259] N4259: ``std::uncaught_exception`` is deprecated since version 20.0. .. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``. .. [#note-P0226] P0226: Progress is tracked `here `_. .. [#note-P0607] P0607: The parts of P0607 that are not done are the ```` bits. diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst index a13496bd0a8fd..a962779cabe93 100644 --- a/libcxx/docs/Status/Cxx20.rst +++ b/libcxx/docs/Status/Cxx20.rst @@ -44,7 +44,7 @@ Paper Status .. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature (the feature-test macro is not set). .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 `__. - .. [#note-P0619] P0619: Section D.4 remains undone. + .. [#note-P0619] P0619: Only sections D.8, D.9, D.10, D.12, and D.13 are implemented. Sections D.4, D.7, and D.11 remain undone. .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0. .. [#note-P0660] P0660: The paper is implemented but the features are experimental and can be enabled via ``-fexperimental-library``. diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst index 8937639bd2bf2..846dfaaf0bef3 100644 --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -215,9 +215,6 @@ C++17 Specific Configuration Macros C++20 Specific Configuration Macros ----------------------------------- -**_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION**: - This macro is used to re-enable `uncaught_exception`. - **_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**: This macro is used to re-enable the function ``std::shared_ptr<...>::unique()``. diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h index 4a0a697c00e6e..0a9c7a7c7f0d8 100644 --- a/libcxx/include/__exception/operations.h +++ b/libcxx/include/__exception/operations.h @@ -29,9 +29,7 @@ using terminate_handler = void (*)(); _LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT; -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION) -_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT; -#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION) +_LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT; class _LIBCPP_EXPORTED_FROM_ABI exception_ptr; diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h index e0698ccb4842a..178359d681567 100644 --- a/libcxx/include/__ostream/basic_ostream.h +++ b/libcxx/include/__ostream/basic_ostream.h @@ -152,7 +152,7 @@ basic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& _ template basic_ostream<_CharT, _Traits>::sentry::~sentry() { - if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) { + if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && !uncaught_exception()) { #ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS diff --git a/libcxx/modules/std/exception.inc b/libcxx/modules/std/exception.inc index 0c110e6e743fb..8e802c7065e0f 100644 --- a/libcxx/modules/std/exception.inc +++ b/libcxx/modules/std/exception.inc @@ -21,5 +21,6 @@ export namespace std { using std::terminate; using std::terminate_handler; using std::throw_with_nested; + using std::uncaught_exception; using std::uncaught_exceptions; } // namespace std diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp index ac6324cd9fe35..ddb186bf8048f 100644 --- a/libcxx/src/exception.cpp +++ b/libcxx/src/exception.cpp @@ -6,9 +6,6 @@ // //===----------------------------------------------------------------------===// -#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION -#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS - #include #include #include From 2841f7201870e8472986f70d59123ac8268e5882 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 3 Aug 2024 23:55:57 +0800 Subject: [PATCH 04/20] Split changes for `uncaught_exception` to another PR (completing) --- libcxx/include/exception | 2 +- .../support.exception/uncaught/uncaught_exception.pass.cpp | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/libcxx/include/exception b/libcxx/include/exception index 64463e02cb16a..5eff8e3f8a4bf 100644 --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -47,7 +47,7 @@ terminate_handler set_terminate(terminate_handler f ) noexcept; terminate_handler get_terminate() noexcept; [[noreturn]] void terminate() noexcept; -bool uncaught_exception() noexcept; // deprecated in C++17, removed in C++20 +bool uncaught_exception() noexcept; int uncaught_exceptions() noexcept; // C++17 typedef unspecified exception_ptr; diff --git a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp index 6fa4cb22070c8..e368ce177b317 100644 --- a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp +++ b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp @@ -7,10 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-exceptions - -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS - // test uncaught_exception #include From 5268aa909b81e3adc765df3748f17fab91823f0a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 5 Aug 2024 01:20:47 +0800 Subject: [PATCH 05/20] Attempt to create `__scoped_temporary_buffer` --- libcxx/include/CMakeLists.txt | 1 + libcxx/include/__algorithm/inplace_merge.h | 15 ++- libcxx/include/__algorithm/stable_partition.h | 18 ++- libcxx/include/__algorithm/stable_sort.h | 10 +- .../__memory/scoped_temporary_buffer.h | 121 ++++++++++++++++++ libcxx/include/__memory/temporary_buffer.h | 58 ++------- libcxx/include/module.modulemap | 1 + .../gn/secondary/libcxx/include/BUILD.gn | 1 + 8 files changed, 162 insertions(+), 63 deletions(-) create mode 100644 libcxx/include/__memory/scoped_temporary_buffer.h diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 32579272858a8..51f404f23c028 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -541,6 +541,7 @@ set(files __memory/ranges_construct_at.h __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h + __memory/scoped_temporary_buffer.h __memory/shared_ptr.h __memory/swap_allocator.h __memory/temp_value.h diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index 4c6ab527c8188..6daa236df7c2f 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -24,7 +24,7 @@ #include <__iterator/iterator_traits.h> #include <__iterator/reverse_iterator.h> #include <__memory/destruct_n.h> -#include <__memory/temporary_buffer.h> +#include <__memory/scoped_temporary_buffer.h> #include <__memory/unique_ptr.h> #include <__utility/pair.h> #include @@ -211,10 +211,17 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = std::min(__len1, __len2); - pair __buf = std::__get_temporary_buffer(__buf_size); - unique_ptr __h(__buf.first); + __scoped_temporary_buffer __scoped_buf(__buf_size); + __temporary_allocation_result __buf_state = __scoped_buf.__get(); return std::__inplace_merge<_AlgPolicy>( - std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); + std::move(__first), + std::move(__middle), + std::move(__last), + __comp, + __len1, + __len2, + __buf_state.__ptr, + __buf_state.__count); } template diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 4f09b87ae0f9a..2209b0d10bdf4 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -16,7 +16,7 @@ #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> -#include <__memory/temporary_buffer.h> +#include <__memory/scoped_temporary_buffer.h> #include <__memory/unique_ptr.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -132,11 +132,13 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred // We now have a reduced range [__first, __last) // *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); + __scoped_temporary_buffer __scoped_buf; pair __p(0, 0); - unique_ptr __h; if (__len >= __alloc_limit) { - __p = std::__get_temporary_buffer(__len); - __h.reset(__p.first); + __scoped_buf.__try_allocate(__len); + __temporary_allocation_result __buf_state = __scoped_buf.__get(); + __p.first = __buf_state.__ptr; + __p.second = __buf_state.__count; } return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); @@ -269,11 +271,13 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( // *__last is known to be true // __len >= 2 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; + __scoped_temporary_buffer __scoped_buf; pair __p(0, 0); - unique_ptr __h; if (__len >= __alloc_limit) { - __p = std::__get_temporary_buffer(__len); - __h.reset(__p.first); + __scoped_buf.__try_allocate(__len); + __temporary_allocation_result __buf_state = __scoped_buf.__get(); + __p.first = __buf_state.__ptr; + __p.second = __buf_state.__count; } return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 69fd85cc798bd..1ecace30ef655 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -18,7 +18,7 @@ #include <__debug_utils/strict_weak_ordering_check.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> -#include <__memory/temporary_buffer.h> +#include <__memory/scoped_temporary_buffer.h> #include <__memory/unique_ptr.h> #include <__type_traits/is_trivially_assignable.h> #include <__utility/move.h> @@ -241,11 +241,13 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; + __scoped_temporary_buffer __scoped_buf; pair __buf(0, 0); - unique_ptr __h; if (__len > static_cast(__stable_sort_switch::value)) { - __buf = std::__get_temporary_buffer(__len); - __h.reset(__buf.first); + __scoped_buf.__try_allocate(__len); + __temporary_allocation_result __buf_state = __scoped_buf.__get(); + __buf.first = __buf_state.__ptr; + __buf.second = __buf_state.__count; } std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h new file mode 100644 index 0000000000000..c9a9d0b730b14 --- /dev/null +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -0,0 +1,121 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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___MEMORY_SCOPED_TEMPORARY_BUFFER_H +#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H + +#include <__config> +#include <__memory/allocator.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __temporary_allocation_result { + _Tp* __ptr; + ptrdiff_t __count; +}; + +template +class __scoped_temporary_buffer { +public: + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __scoped_temporary_buffer() _NOEXCEPT + : __ptr_(NULL), + __count_(0) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __scoped_temporary_buffer(ptrdiff_t __count) _NOEXCEPT + : __ptr_(NULL), + __count_(0) { + __try_allocate(__count); + } + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + // pre: __buf_ptr points to the beginning of a previously allocated scoped temporary buffer or is null + // notes: __count_ is ignored in non-constant evaluation + _LIBCPP_HIDE_FROM_ABI explicit __scoped_temporary_buffer(_Tp* __buf_ptr) _NOEXCEPT : __ptr_(__buf_ptr), __count_(0) {} +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) { + allocator<_Tp>().deallocate(__ptr_, __count_); + } + + std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp)); + } + + __scoped_temporary_buffer(const __scoped_temporary_buffer&) = delete; + __scoped_temporary_buffer& operator=(const __scoped_temporary_buffer&) = delete; + + // pre: __ptr_ == nullptr && __count_ == 0 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __try_allocate(ptrdiff_t __count) _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) { + __ptr_ = allocator<_Tp>().allocate(__count); + __count_ = __count; + return; + } + + const ptrdiff_t __max_count = + (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp); + if (__count > __max_count) + __count = __max_count; + while (__count > 0) { +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { + align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp)); + __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), __al, nothrow)); + } else { + __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); + } +#else + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { + // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment. + return; + } + + __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); +#endif + + if (__ptr_) { + __count_ = __count; + break; + } + __count_ /= 2; + } + } + + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __temporary_allocation_result<_Tp> + __get() const _NOEXCEPT { + __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; + return __result; + } + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release() _NOEXCEPT { + __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; + + __ptr_ = NULL; + __count_ = 0; + + return __result; + } +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + +private: + _Tp* __ptr_; + ptrdiff_t __count_; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index c6cb338905184..ecd6e86099f45 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -11,6 +11,7 @@ #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H #include <__config> +#include <__memory/scoped_temporary_buffer.h> #include <__utility/pair.h> #include #include @@ -19,65 +20,26 @@ # pragma GCC system_header #endif -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t> -__get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { - pair<_Tp*, ptrdiff_t> __r(0, 0); - const ptrdiff_t __m = - (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp); - if (__n > __m) - __n = __m; - while (__n > 0) { -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { - align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp)); - __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al, nothrow)); - } else { - __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); - } -#else - if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { - // Since aligned operator new is unavailable, return an empty - // buffer rather than one with invalid alignment. - return __r; - } - - __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); -#endif - - if (__r.first) { - __r.second = __n; - break; - } - __n /= 2; - } - return __r; -} - -struct __return_temporary_buffer { - template - _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) const { - std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); - } -}; - #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) +_LIBCPP_BEGIN_NAMESPACE_STD + template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { - return std::__get_temporary_buffer<_Tp>(__n); + __scoped_temporary_buffer<_Tp> __scoped_buf(__n); + __temporary_allocation_result<_Tp> __result = __scoped_buf.__release(); + return pair<_Tp*, ptrdiff_t>(__result.__ptr, __result.__count); } template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); + __scoped_temporary_buffer __scoped_buf(__p); + (void)__scoped_buf; } -#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) - _LIBCPP_END_NAMESPACE_STD +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + #endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 13d0dce34d97e..70faf49f4feec 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1532,6 +1532,7 @@ module std_private_memory_ranges_uninitialized_algorithms [system] { export std_private_algorithm_in_out_result } module std_private_memory_raw_storage_iterator [system] { header "__memory/raw_storage_iterator.h" } +module std_private_memory_scoped_temporary_buffer [system] { header "__memory/scoped_temporary_buffer.h" } module std_private_memory_shared_ptr [system] { header "__memory/shared_ptr.h" export std_private_memory_uninitialized_algorithms diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn index cc759d2337516..9ecd5caf40481 100644 --- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn +++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn @@ -612,6 +612,7 @@ if (current_toolchain == default_toolchain) { "__memory/ranges_construct_at.h", "__memory/ranges_uninitialized_algorithms.h", "__memory/raw_storage_iterator.h", + "__memory/scoped_temporary_buffer.h", "__memory/shared_ptr.h", "__memory/swap_allocator.h", "__memory/temp_value.h", From 352900791d6fa36799a86a41e82c871330f74cbc Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 5 Aug 2024 07:39:48 +0800 Subject: [PATCH 06/20] Try to fix errors: module map, no CTAD --- libcxx/include/__memory/temporary_buffer.h | 2 +- libcxx/include/module.modulemap | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index ecd6e86099f45..f298a6840d54e 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -34,7 +34,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - __scoped_temporary_buffer __scoped_buf(__p); + __scoped_temporary_buffer<_Tp> __scoped_buf(__p); (void)__scoped_buf; } diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 70faf49f4feec..ad39c0f37ab34 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1532,7 +1532,10 @@ module std_private_memory_ranges_uninitialized_algorithms [system] { export std_private_algorithm_in_out_result } module std_private_memory_raw_storage_iterator [system] { header "__memory/raw_storage_iterator.h" } -module std_private_memory_scoped_temporary_buffer [system] { header "__memory/scoped_temporary_buffer.h" } +module std_private_memory_scoped_temporary_buffer [system] { + header "__memory/scoped_temporary_buffer.h" + export std_private_type_traits_is_constant_evaluated +} module std_private_memory_shared_ptr [system] { header "__memory/shared_ptr.h" export std_private_memory_uninitialized_algorithms From 2a71c0e14a4c490e7384459a538449a61d0f898c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 5 Aug 2024 09:22:40 +0800 Subject: [PATCH 07/20] Try to fix inclusion error for `__libcpp_is_constant_evaluated` --- libcxx/include/__memory/scoped_temporary_buffer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h index c9a9d0b730b14..c92b8a33f7db1 100644 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -12,6 +12,7 @@ #include <__config> #include <__memory/allocator.h> +#include <__type_traits/is_constant_evaluated.h> #include #include From 6d42fd6f2ee255beb8311dcfe951e9f3f028b85d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 5 Aug 2024 09:43:13 +0800 Subject: [PATCH 08/20] Release `__release` to `__release_to_raw` --- libcxx/include/__memory/scoped_temporary_buffer.h | 2 +- libcxx/include/__memory/temporary_buffer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h index c92b8a33f7db1..ca6e3d4e9c401 100644 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -102,7 +102,7 @@ class __scoped_temporary_buffer { } #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release() _NOEXCEPT { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT { __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; __ptr_ = NULL; diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index f298a6840d54e..bdacf65dac925 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -28,7 +28,7 @@ template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { __scoped_temporary_buffer<_Tp> __scoped_buf(__n); - __temporary_allocation_result<_Tp> __result = __scoped_buf.__release(); + __temporary_allocation_result<_Tp> __result = __scoped_buf.__release_to_raw(); return pair<_Tp*, ptrdiff_t>(__result.__ptr, __result.__count); } From b83103b97fa1e602b6cbb8fc4ace7cf5c4a77bfc Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 28 Aug 2024 14:49:48 +0800 Subject: [PATCH 09/20] Avoid UB in deallocating null pointer value --- libcxx/include/__memory/scoped_temporary_buffer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h index ca6e3d4e9c401..8807089aba045 100644 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -49,7 +49,9 @@ class __scoped_temporary_buffer { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT { if (__libcpp_is_constant_evaluated()) { - allocator<_Tp>().deallocate(__ptr_, __count_); + if (__ptr_) + allocator<_Tp>().deallocate(__ptr_, __count_); + return; } std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp)); From c812180b0474d02f8f892dc0f55798b2de5c12e5 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 28 Aug 2024 14:50:25 +0800 Subject: [PATCH 10/20] Make legacy member functions unconditionally available --- libcxx/include/__memory/scoped_temporary_buffer.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h index 8807089aba045..59fbcf09c7a87 100644 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -41,11 +41,10 @@ class __scoped_temporary_buffer { __try_allocate(__count); } -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) + // This constructor is only needed to implement get_temporary_buffer(). // pre: __buf_ptr points to the beginning of a previously allocated scoped temporary buffer or is null // notes: __count_ is ignored in non-constant evaluation _LIBCPP_HIDE_FROM_ABI explicit __scoped_temporary_buffer(_Tp* __buf_ptr) _NOEXCEPT : __ptr_(__buf_ptr), __count_(0) {} -#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT { if (__libcpp_is_constant_evaluated()) { @@ -103,7 +102,6 @@ class __scoped_temporary_buffer { return __result; } -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT { __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; @@ -112,7 +110,6 @@ class __scoped_temporary_buffer { return __result; } -#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER) private: _Tp* __ptr_; From f6e94f7640a0a4c045389bce3ce02282ef55e7a2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 28 Aug 2024 14:53:26 +0800 Subject: [PATCH 11/20] Also add comment for `__release_to_raw` --- libcxx/include/__memory/scoped_temporary_buffer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h index 59fbcf09c7a87..727dbf9efce28 100644 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -102,6 +102,7 @@ class __scoped_temporary_buffer { return __result; } + // This member function is only needed to implement get_temporary_buffer(). _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT { __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; From 5c50d6a0dd73b40c446ca3bd7da938644920c83f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 14:31:27 +0800 Subject: [PATCH 12/20] Use `nullptr` and internal assertion from review comments --- libcxx/include/__memory/scoped_temporary_buffer.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h index 727dbf9efce28..92c745408a260 100644 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ b/libcxx/include/__memory/scoped_temporary_buffer.h @@ -10,7 +10,9 @@ #ifndef _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H #define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H +#include <__assert> #include <__config> + #include <__memory/allocator.h> #include <__type_traits/is_constant_evaluated.h> #include @@ -32,11 +34,11 @@ template class __scoped_temporary_buffer { public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __scoped_temporary_buffer() _NOEXCEPT - : __ptr_(NULL), + : __ptr_(nullptr), __count_(0) {} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __scoped_temporary_buffer(ptrdiff_t __count) _NOEXCEPT - : __ptr_(NULL), + : __ptr_(nullptr), __count_(0) { __try_allocate(__count); } @@ -61,6 +63,9 @@ class __scoped_temporary_buffer { // pre: __ptr_ == nullptr && __count_ == 0 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __try_allocate(ptrdiff_t __count) _NOEXCEPT { + _LIBCPP_ASSERT_INTERNAL(__ptr_ == nullptr && __count_ == 0, + "There must be no dynamically allocator buffer before calling __try_allocate()."); + if (__libcpp_is_constant_evaluated()) { __ptr_ = allocator<_Tp>().allocate(__count); __count_ = __count; @@ -106,7 +111,7 @@ class __scoped_temporary_buffer { _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT { __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; - __ptr_ = NULL; + __ptr_ = nullptr; __count_ = 0; return __result; From b8de11de85938b0fc147c518eaf47976aa815686 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 14:35:24 +0800 Subject: [PATCH 13/20] Restore the note changes in Cxx20Papers.csv --- libcxx/docs/Status/Cxx20Papers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv index ad788d7416fda..7c08557ef7666 100644 --- a/libcxx/docs/Status/Cxx20Papers.csv +++ b/libcxx/docs/Status/Cxx20Papers.csv @@ -34,7 +34,7 @@ "`P0528R3 `__","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","2018-06 (Rapperswil)","","","" "`P0542R5 `__","Support for contract based programming in C++","2018-06 (Rapperswil)","|Nothing To Do|","n/a","Pulled at the 2019-07 meeting in Cologne" "`P0556R3 `__","Integral power-of-2 operations","2018-06 (Rapperswil)","|Complete|","9.0","" -"`P0619R4 `__","Reviewing Deprecated Facilities of C++17 for C++20","2018-06 (Rapperswil)","|Partial|","","Only sections D.7, D.8, D.9, D.10, D.11 and D.13 are implemented. Sections D.4 and D.12 remain undone." +"`P0619R4 `__","Reviewing Deprecated Facilities of C++17 for C++20","2018-06 (Rapperswil)","|Partial|","","Only sections D.7, D.8, D.9, D.10, D.11, D.12, and D.13 are implemented. Section D.4 remains undone." "`P0646R1 `__","Improving the Return Value of Erase-Like Algorithms","2018-06 (Rapperswil)","|Complete|","10.0","" "`P0722R3 `__","Efficient sized delete for variable sized classes","2018-06 (Rapperswil)","|Complete|","9.0","" "`P0758R1 `__","Implicit conversion traits and utility functions","2018-06 (Rapperswil)","|Complete|","","" From 1f3fde76398c0125887991157efc75c0ba93eb18 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 16:37:29 +0800 Subject: [PATCH 14/20] Switch to use `unique_ptr`-based approach --- libcxx/include/CMakeLists.txt | 2 +- libcxx/include/__algorithm/inplace_merge.h | 10 +- libcxx/include/__algorithm/stable_partition.h | 20 ++- libcxx/include/__algorithm/stable_sort.h | 11 +- .../__memory/scoped_temporary_buffer.h | 127 ------------------ libcxx/include/__memory/temporary_buffer.h | 14 +- .../__memory/unique_temporary_buffer.h | 89 ++++++++++++ libcxx/include/module.modulemap | 8 +- .../gn/secondary/libcxx/include/BUILD.gn | 2 +- 9 files changed, 122 insertions(+), 161 deletions(-) delete mode 100644 libcxx/include/__memory/scoped_temporary_buffer.h create mode 100644 libcxx/include/__memory/unique_temporary_buffer.h diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 51f404f23c028..782f2b79993af 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -541,13 +541,13 @@ set(files __memory/ranges_construct_at.h __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h - __memory/scoped_temporary_buffer.h __memory/shared_ptr.h __memory/swap_allocator.h __memory/temp_value.h __memory/temporary_buffer.h __memory/uninitialized_algorithms.h __memory/unique_ptr.h + __memory/unique_temporary_buffer.h __memory/uses_allocator.h __memory/uses_allocator_construction.h __memory/voidify.h diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index 6daa236df7c2f..4e04241b3266a 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -24,8 +24,8 @@ #include <__iterator/iterator_traits.h> #include <__iterator/reverse_iterator.h> #include <__memory/destruct_n.h> -#include <__memory/scoped_temporary_buffer.h> #include <__memory/unique_ptr.h> +#include <__memory/unique_temporary_buffer.h> #include <__utility/pair.h> #include @@ -211,8 +211,8 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = std::min(__len1, __len2); - __scoped_temporary_buffer __scoped_buf(__buf_size); - __temporary_allocation_result __buf_state = __scoped_buf.__get(); + unique_ptr> __unique_buf = + std::__make_unique_sized_temporary_buffer(__buf_size); return std::__inplace_merge<_AlgPolicy>( std::move(__first), std::move(__middle), @@ -220,8 +220,8 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( __comp, __len1, __len2, - __buf_state.__ptr, - __buf_state.__count); + __unique_buf.get(), + __unique_buf.get_deleter().__count_); } template diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 2209b0d10bdf4..5bf74957de4e1 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -16,8 +16,8 @@ #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> -#include <__memory/scoped_temporary_buffer.h> #include <__memory/unique_ptr.h> +#include <__memory/unique_temporary_buffer.h> #include <__utility/move.h> #include <__utility/pair.h> #include @@ -132,13 +132,12 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred // We now have a reduced range [__first, __last) // *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - __scoped_temporary_buffer __scoped_buf; + unique_ptr> __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { - __scoped_buf.__try_allocate(__len); - __temporary_allocation_result __buf_state = __scoped_buf.__get(); - __p.first = __buf_state.__ptr; - __p.second = __buf_state.__count; + __unique_buf = std::__make_unique_sized_temporary_buffer(__len); + __p.first = __unique_buf.get(); + __p.second = __unique_buf.get_deleter().__count_; } return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); @@ -271,13 +270,12 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( // *__last is known to be true // __len >= 2 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - __scoped_temporary_buffer __scoped_buf; + unique_ptr> __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { - __scoped_buf.__try_allocate(__len); - __temporary_allocation_result __buf_state = __scoped_buf.__get(); - __p.first = __buf_state.__ptr; - __p.second = __buf_state.__count; + __unique_buf = std::__make_unique_sized_temporary_buffer(__len); + __p.first = __unique_buf.get(); + __p.second = __unique_buf.get_deleter().__count_; } return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 1ecace30ef655..4599e9748e0b1 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -18,8 +18,8 @@ #include <__debug_utils/strict_weak_ordering_check.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> -#include <__memory/scoped_temporary_buffer.h> #include <__memory/unique_ptr.h> +#include <__memory/unique_temporary_buffer.h> #include <__type_traits/is_trivially_assignable.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -241,13 +241,12 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; - __scoped_temporary_buffer __scoped_buf; + unique_ptr> __unique_buf; pair __buf(0, 0); if (__len > static_cast(__stable_sort_switch::value)) { - __scoped_buf.__try_allocate(__len); - __temporary_allocation_result __buf_state = __scoped_buf.__get(); - __buf.first = __buf_state.__ptr; - __buf.second = __buf_state.__count; + __unique_buf = std::__make_unique_sized_temporary_buffer(__len); + __p.first = __unique_buf.get(); + __p.second = __unique_buf.get_deleter().__count_; } std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h deleted file mode 100644 index 92c745408a260..0000000000000 --- a/libcxx/include/__memory/scoped_temporary_buffer.h +++ /dev/null @@ -1,127 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// 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___MEMORY_SCOPED_TEMPORARY_BUFFER_H -#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H - -#include <__assert> -#include <__config> - -#include <__memory/allocator.h> -#include <__type_traits/is_constant_evaluated.h> -#include -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -struct __temporary_allocation_result { - _Tp* __ptr; - ptrdiff_t __count; -}; - -template -class __scoped_temporary_buffer { -public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __scoped_temporary_buffer() _NOEXCEPT - : __ptr_(nullptr), - __count_(0) {} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __scoped_temporary_buffer(ptrdiff_t __count) _NOEXCEPT - : __ptr_(nullptr), - __count_(0) { - __try_allocate(__count); - } - - // This constructor is only needed to implement get_temporary_buffer(). - // pre: __buf_ptr points to the beginning of a previously allocated scoped temporary buffer or is null - // notes: __count_ is ignored in non-constant evaluation - _LIBCPP_HIDE_FROM_ABI explicit __scoped_temporary_buffer(_Tp* __buf_ptr) _NOEXCEPT : __ptr_(__buf_ptr), __count_(0) {} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT { - if (__libcpp_is_constant_evaluated()) { - if (__ptr_) - allocator<_Tp>().deallocate(__ptr_, __count_); - return; - } - - std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp)); - } - - __scoped_temporary_buffer(const __scoped_temporary_buffer&) = delete; - __scoped_temporary_buffer& operator=(const __scoped_temporary_buffer&) = delete; - - // pre: __ptr_ == nullptr && __count_ == 0 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __try_allocate(ptrdiff_t __count) _NOEXCEPT { - _LIBCPP_ASSERT_INTERNAL(__ptr_ == nullptr && __count_ == 0, - "There must be no dynamically allocator buffer before calling __try_allocate()."); - - if (__libcpp_is_constant_evaluated()) { - __ptr_ = allocator<_Tp>().allocate(__count); - __count_ = __count; - return; - } - - const ptrdiff_t __max_count = - (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp); - if (__count > __max_count) - __count = __max_count; - while (__count > 0) { -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { - align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp)); - __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), __al, nothrow)); - } else { - __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); - } -#else - if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { - // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment. - return; - } - - __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); -#endif - - if (__ptr_) { - __count_ = __count; - break; - } - __count_ /= 2; - } - } - - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __temporary_allocation_result<_Tp> - __get() const _NOEXCEPT { - __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; - return __result; - } - - // This member function is only needed to implement get_temporary_buffer(). - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT { - __temporary_allocation_result<_Tp> __result = {__ptr_, __count_}; - - __ptr_ = nullptr; - __count_ = 0; - - return __result; - } - -private: - _Tp* __ptr_; - ptrdiff_t __count_; -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index bdacf65dac925..51ac9e63a0fa3 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -11,7 +11,7 @@ #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H #include <__config> -#include <__memory/scoped_temporary_buffer.h> +#include <__memory/unique_temporary_buffer.h> #include <__utility/pair.h> #include #include @@ -27,15 +27,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { - __scoped_temporary_buffer<_Tp> __scoped_buf(__n); - __temporary_allocation_result<_Tp> __result = __scoped_buf.__release_to_raw(); - return pair<_Tp*, ptrdiff_t>(__result.__ptr, __result.__count); + unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf = + std::__make_unique_sized_temporary_buffer<_Tp>(__n); + pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_); + __unique_buf.release(); + return __result; } template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - __scoped_temporary_buffer<_Tp> __scoped_buf(__p); - (void)__scoped_buf; + unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf(__p, 0); + (void)__unique_buf; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h new file mode 100644 index 0000000000000..df0d4537a625a --- /dev/null +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -0,0 +1,89 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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___MEMORY_SCOPED_TEMPORARY_BUFFER_H +#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H + +#include <__assert> +#include <__config> + +#include <__memory/allocator.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/is_constant_evaluated.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __sized_temporary_buffer_deleter { + ptrdiff_t __count_; // ignored in non-constant evaluation + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __sized_temporary_buffer_deleter() _NOEXCEPT : __count_(0) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __sized_temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT + : __count_(__count) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) { + allocator<_Tp>().deallocate(__ptr_, __count_); + return; + } + + std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp)); + } +}; + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> +__make_unique_sized_temporary_buffer(ptrdiff_t __count) { + typedef __sized_temporary_buffer_deleter<_Tp> __deleter_type; + typedef unique_ptr<_Tp, __deleter_type> __unique_buffer_type; + + if (__libcpp_is_constant_evaluated()) { + return __unique_buffer_type(allocator<_Tp>().allocate(__count), __deleter_type(__count)); + } + + _Tp* __ptr = nullptr; + const ptrdiff_t __max_count = + (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp); + if (__count > __max_count) + __count = __max_count; + while (__count > 0) { +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { + align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp)); + __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), __al, nothrow)); + } else { + __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); + } +#else + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { + // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment. + return; + } + + __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); +#endif + + if (__ptr) { + break; + } + __count /= 2; + } + + return __unique_buffer_type(__ptr, __deleter_type(__count)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index de16df9c5f6ab..b1d566c12fbae 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1539,10 +1539,6 @@ module std_private_memory_ranges_uninitialized_algorithms [system] { export std_private_algorithm_in_out_result } module std_private_memory_raw_storage_iterator [system] { header "__memory/raw_storage_iterator.h" } -module std_private_memory_scoped_temporary_buffer [system] { - header "__memory/scoped_temporary_buffer.h" - export std_private_type_traits_is_constant_evaluated -} module std_private_memory_shared_ptr [system] { header "__memory/shared_ptr.h" export std_private_memory_uninitialized_algorithms @@ -1563,6 +1559,10 @@ module std_private_memory_unique_ptr [system] { export std_private_type_traits_is_pointer export std_private_type_traits_type_identity } +module std_private_memory_unique_temporary_buffer [system] { + header "__memory/unique_temporary_buffer.h" + export std_private_type_traits_is_constant_evaluated +} module std_private_memory_uses_allocator [system] { header "__memory/uses_allocator.h" } module std_private_memory_uses_allocator_construction [system] { header "__memory/uses_allocator_construction.h" } module std_private_memory_voidify [system] { header "__memory/voidify.h" } diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn index 8a2d3214dd98e..af97d76b497a4 100644 --- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn +++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn @@ -613,13 +613,13 @@ if (current_toolchain == default_toolchain) { "__memory/ranges_construct_at.h", "__memory/ranges_uninitialized_algorithms.h", "__memory/raw_storage_iterator.h", - "__memory/scoped_temporary_buffer.h", "__memory/shared_ptr.h", "__memory/swap_allocator.h", "__memory/temp_value.h", "__memory/temporary_buffer.h", "__memory/uninitialized_algorithms.h", "__memory/unique_ptr.h", + "__memory/unique_temporary_buffer.h", "__memory/uses_allocator.h", "__memory/uses_allocator_construction.h", "__memory/voidify.h", From 5e4b15732367ceb25e21a241c8c7e922ef335a44 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 16:48:50 +0800 Subject: [PATCH 15/20] Fix copy-pasta --- libcxx/include/__algorithm/stable_sort.h | 4 ++-- libcxx/include/__memory/unique_temporary_buffer.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 4599e9748e0b1..2e7b84c7a93be 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -245,8 +245,8 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, pair __buf(0, 0); if (__len > static_cast(__stable_sort_switch::value)) { __unique_buf = std::__make_unique_sized_temporary_buffer(__len); - __p.first = __unique_buf.get(); - __p.second = __unique_buf.get_deleter().__count_; + __buf.first = __unique_buf.get(); + __buf.second = __unique_buf.get_deleter().__count_; } std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index df0d4537a625a..dc680ba034a96 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H -#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H +#ifndef _LIBCPP___MEMORY_UNIQUE_TEMPORARY_BUFFER_H +#define _LIBCPP___MEMORY_UNIQUE_TEMPORARY_BUFFER_H #include <__assert> #include <__config> @@ -35,11 +35,11 @@ struct __sized_temporary_buffer_deleter { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT { if (__libcpp_is_constant_evaluated()) { - allocator<_Tp>().deallocate(__ptr_, __count_); + allocator<_Tp>().deallocate(__ptr, __count_); return; } - std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp)); + std::__libcpp_deallocate_unsized((void*)__ptr, _LIBCPP_ALIGNOF(_Tp)); } }; @@ -86,4 +86,4 @@ __make_unique_sized_temporary_buffer(ptrdiff_t __count) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H +#endif // _LIBCPP___MEMORY_UNIQUE_TEMPORARY_BUFFER_H From 2bd52cb6f7c0206c112f0fc1461c9970d60181a3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 17:09:36 +0800 Subject: [PATCH 16/20] Fix CI failures - C++03 `> >` - Module exporting - `unique_ptr` construction --- libcxx/include/__algorithm/inplace_merge.h | 2 +- libcxx/include/__algorithm/stable_partition.h | 4 ++-- libcxx/include/__algorithm/stable_sort.h | 2 +- libcxx/include/__memory/temporary_buffer.h | 4 ++-- libcxx/include/__memory/unique_temporary_buffer.h | 2 +- libcxx/include/module.modulemap | 1 + 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index 4e04241b3266a..f510307503ef1 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -211,7 +211,7 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = std::min(__len1, __len2); - unique_ptr> __unique_buf = + unique_ptr > __unique_buf = std::__make_unique_sized_temporary_buffer(__buf_size); return std::__inplace_merge<_AlgPolicy>( std::move(__first), diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 5bf74957de4e1..9dd6792de368a 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -132,7 +132,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred // We now have a reduced range [__first, __last) // *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - unique_ptr> __unique_buf; + unique_ptr > __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { __unique_buf = std::__make_unique_sized_temporary_buffer(__len); @@ -270,7 +270,7 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( // *__last is known to be true // __len >= 2 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - unique_ptr> __unique_buf; + unique_ptr > __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { __unique_buf = std::__make_unique_sized_temporary_buffer(__len); diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 2e7b84c7a93be..af98b77535c4a 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -241,7 +241,7 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; - unique_ptr> __unique_buf; + unique_ptr > __unique_buf; pair __buf(0, 0); if (__len > static_cast(__stable_sort_switch::value)) { __unique_buf = std::__make_unique_sized_temporary_buffer(__len); diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index 51ac9e63a0fa3..9de9074e01b2c 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { - unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf = + unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf = std::__make_unique_sized_temporary_buffer<_Tp>(__n); pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_); __unique_buf.release(); @@ -36,7 +36,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf(__p, 0); + unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf(__p); (void)__unique_buf; } diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index dc680ba034a96..63dee2208faf8 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -44,7 +44,7 @@ struct __sized_temporary_buffer_deleter { }; template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __make_unique_sized_temporary_buffer(ptrdiff_t __count) { typedef __sized_temporary_buffer_deleter<_Tp> __deleter_type; typedef unique_ptr<_Tp, __deleter_type> __unique_buffer_type; diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index b1d566c12fbae..bae1eb491bfbb 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1561,6 +1561,7 @@ module std_private_memory_unique_ptr [system] { } module std_private_memory_unique_temporary_buffer [system] { header "__memory/unique_temporary_buffer.h" + export std_private_memory_unique_ptr export std_private_type_traits_is_constant_evaluated } module std_private_memory_uses_allocator [system] { header "__memory/uses_allocator.h" } From 51b18a2c5da3a85a1c9119b40adea23e57c19d4d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 18:44:22 +0800 Subject: [PATCH 17/20] Fix bad `return;` --- libcxx/include/__memory/unique_temporary_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index 63dee2208faf8..b743191753bee 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -69,7 +69,7 @@ __make_unique_sized_temporary_buffer(ptrdiff_t __count) { #else if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment. - return; + return __unique_buffer_type(); } __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow)); From 0961a501ae94c5030578d11c714d22ac83fdbb21 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 21:36:27 +0800 Subject: [PATCH 18/20] Address review comments for `unique_ptr`-based buffer --- libcxx/include/__algorithm/inplace_merge.h | 4 ++-- libcxx/include/__algorithm/stable_partition.h | 8 ++++---- libcxx/include/__algorithm/stable_sort.h | 4 ++-- libcxx/include/__memory/temporary_buffer.h | 5 ++--- libcxx/include/__memory/unique_temporary_buffer.h | 14 +++++++------- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index f510307503ef1..79e68d0d57bc7 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -211,8 +211,8 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = std::min(__len1, __len2); - unique_ptr > __unique_buf = - std::__make_unique_sized_temporary_buffer(__buf_size); + unique_ptr > __unique_buf = + std::__allocate_unique_temporary_buffer(__buf_size); return std::__inplace_merge<_AlgPolicy>( std::move(__first), std::move(__middle), diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 9dd6792de368a..81452bf5a230d 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -132,10 +132,10 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred // We now have a reduced range [__first, __last) // *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - unique_ptr > __unique_buf; + unique_ptr > __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { - __unique_buf = std::__make_unique_sized_temporary_buffer(__len); + __unique_buf = std::__allocate_unique_temporary_buffer(__len); __p.first = __unique_buf.get(); __p.second = __unique_buf.get_deleter().__count_; } @@ -270,10 +270,10 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( // *__last is known to be true // __len >= 2 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - unique_ptr > __unique_buf; + unique_ptr > __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { - __unique_buf = std::__make_unique_sized_temporary_buffer(__len); + __unique_buf = std::__allocate_unique_temporary_buffer(__len); __p.first = __unique_buf.get(); __p.second = __unique_buf.get_deleter().__count_; } diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index af98b77535c4a..e47d1e0334298 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -241,10 +241,10 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; - unique_ptr > __unique_buf; + unique_ptr > __unique_buf; pair __buf(0, 0); if (__len > static_cast(__stable_sort_switch::value)) { - __unique_buf = std::__make_unique_sized_temporary_buffer(__len); + __unique_buf = std::__allocate_unique_temporary_buffer(__len); __buf.first = __unique_buf.get(); __buf.second = __unique_buf.get_deleter().__count_; } diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index 9de9074e01b2c..acb8910336bf1 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -27,8 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { - unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf = - std::__make_unique_sized_temporary_buffer<_Tp>(__n); + unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n); pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_); __unique_buf.release(); return __result; @@ -36,7 +35,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf(__p); + unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf(__p); (void)__unique_buf; } diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index b743191753bee..cfb770cc0dee4 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -26,11 +26,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct __sized_temporary_buffer_deleter { +struct __temporary_buffer_deleter { ptrdiff_t __count_; // ignored in non-constant evaluation - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __sized_temporary_buffer_deleter() _NOEXCEPT : __count_(0) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __sized_temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __temporary_buffer_deleter() _NOEXCEPT : __count_(0) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT : __count_(__count) {} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT { @@ -44,10 +44,10 @@ struct __sized_temporary_buffer_deleter { }; template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > -__make_unique_sized_temporary_buffer(ptrdiff_t __count) { - typedef __sized_temporary_buffer_deleter<_Tp> __deleter_type; - typedef unique_ptr<_Tp, __deleter_type> __unique_buffer_type; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > +__allocate_unique_temporary_buffer(ptrdiff_t __count) { + using __deleter_type = __temporary_buffer_deleter<_Tp>; + using __unique_buffer_type = unique_ptr<_Tp, __deleter_type>; if (__libcpp_is_constant_evaluated()) { return __unique_buffer_type(allocator<_Tp>().allocate(__count), __deleter_type(__count)); From dc503fa4b844639c6f2cf4938628cd974972a0f8 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 21:40:28 +0800 Subject: [PATCH 19/20] Use alias template --- libcxx/include/__algorithm/inplace_merge.h | 9 ++++----- libcxx/include/__algorithm/stable_partition.h | 4 ++-- libcxx/include/__algorithm/stable_sort.h | 2 +- libcxx/include/__memory/temporary_buffer.h | 4 ++-- libcxx/include/__memory/unique_temporary_buffer.h | 7 +++++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index 79e68d0d57bc7..2133f440d2fea 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -208,11 +208,10 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge( _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); - difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); - difference_type __buf_size = std::min(__len1, __len2); - unique_ptr > __unique_buf = - std::__allocate_unique_temporary_buffer(__buf_size); + difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); + difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); + difference_type __buf_size = std::min(__len1, __len2); + __unique_temporary_buffer __unique_buf = std::__allocate_unique_temporary_buffer(__buf_size); return std::__inplace_merge<_AlgPolicy>( std::move(__first), std::move(__middle), diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 81452bf5a230d..bf86201dbb6a6 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -132,7 +132,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred // We now have a reduced range [__first, __last) // *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - unique_ptr > __unique_buf; + __unique_temporary_buffer __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { __unique_buf = std::__allocate_unique_temporary_buffer(__len); @@ -270,7 +270,7 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( // *__last is known to be true // __len >= 2 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - unique_ptr > __unique_buf; + __unique_temporary_buffer __unique_buf; pair __p(0, 0); if (__len >= __alloc_limit) { __unique_buf = std::__allocate_unique_temporary_buffer(__len); diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index e47d1e0334298..ec556aad82e8d 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -241,7 +241,7 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; - unique_ptr > __unique_buf; + __unique_temporary_buffer __unique_buf; pair __buf(0, 0); if (__len > static_cast(__stable_sort_switch::value)) { __unique_buf = std::__allocate_unique_temporary_buffer(__len); diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index acb8910336bf1..1a4498572c905 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { - unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n); + __unique_temporary_buffer<_Tp> __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n); pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_); __unique_buf.release(); return __result; @@ -35,7 +35,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf(__p); + __unique_temporary_buffer<_Tp> __unique_buf(__p); (void)__unique_buf; } diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index cfb770cc0dee4..a505610957e15 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -44,10 +44,13 @@ struct __temporary_buffer_deleter { }; template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > +using __unique_temporary_buffer = unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> >; + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __unique_temporary_buffer<_Tp> __allocate_unique_temporary_buffer(ptrdiff_t __count) { using __deleter_type = __temporary_buffer_deleter<_Tp>; - using __unique_buffer_type = unique_ptr<_Tp, __deleter_type>; + using __unique_buffer_type = __unique_temporary_buffer<_Tp>; if (__libcpp_is_constant_evaluated()) { return __unique_buffer_type(allocator<_Tp>().allocate(__count), __deleter_type(__count)); From 1406cd51896dd66f3f0d3b1d9cbf364a88f51bc4 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 1 Sep 2024 21:53:06 +0800 Subject: [PATCH 20/20] Clang-format for CI purpose --- libcxx/include/__memory/unique_temporary_buffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index a505610957e15..b9e2a47332682 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -30,8 +30,8 @@ struct __temporary_buffer_deleter { ptrdiff_t __count_; // ignored in non-constant evaluation _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __temporary_buffer_deleter() _NOEXCEPT : __count_(0) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT - : __count_(__count) {} + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR explicit __temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT : __count_(__count) {} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT { if (__libcpp_is_constant_evaluated()) {