[libcxx] [llvm] [libc++] Remove `get_temporary_buffer`/`return_temporary_buffer` (PR #100914)
A. Jiang via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 4 10:22:57 PDT 2024
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/100914
>From f7ff07eca878d623777ab440e1f82dd93e273826 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 28 Jul 2024 14:02:52 +0800
Subject: [PATCH 1/5] [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 <https://https://libcxx.llvm.org/Status/SpecialMath.html>`_.
.. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` 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 <https://wg21.link/n4169>`__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7"
"`N4190 <https://wg21.link/n4190>`__","LWG","Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.","Urbana","|Complete|","15.0"
"`N4258 <https://wg21.link/n4258>`__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7"
-"`N4259 <https://wg21.link/n4259>`__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7"
+"`N4259 <https://wg21.link/n4259>`__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete| [#note-N4259]_","3.7"
"`N4277 <https://wg21.link/n4277>`__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2"
"`N4279 <https://wg21.link/n4279>`__","LWG","Improved insertion interface for unique-key maps.","Urbana","|Complete|","3.7"
"`N4280 <https://wg21.link/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 <https://llvm.org/PR45368>`__.
- .. [#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<value_type*, ptrdiff_t> __buf = std::get_temporary_buffer<value_type>(__buf_size);
- _LIBCPP_SUPPRESS_DEPRECATED_POP
+ pair<value_type*, ptrdiff_t> __buf = std::__get_temporary_buffer<value_type>(__buf_size);
unique_ptr<value_type, __return_temporary_buffer> __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<value_type*, ptrdiff_t> __p(0, 0);
unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len >= __alloc_limit) {
- // TODO: Remove the use of std::get_temporary_buffer
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- __p = std::get_temporary_buffer<value_type>(__len);
- _LIBCPP_SUPPRESS_DEPRECATED_POP
+ __p = std::__get_temporary_buffer<value_type>(__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<value_type*, ptrdiff_t> __p(0, 0);
unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len >= __alloc_limit) {
- // TODO: Remove the use of std::get_temporary_buffer
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- __p = std::get_temporary_buffer<value_type>(__len);
- _LIBCPP_SUPPRESS_DEPRECATED_POP
+ __p = std::__get_temporary_buffer<value_type>(__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<value_type*, ptrdiff_t> __buf(0, 0);
unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
- // TODO: Remove the use of std::get_temporary_buffer
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- __buf = std::get_temporary_buffer<value_type>(__len);
- _LIBCPP_SUPPRESS_DEPRECATED_POP
+ __buf = std::__get_temporary_buffer<value_type>(__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 <class _Tp>
-_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 <class _Tp>
-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 <class _Tp>
_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 <class _Tp>
+_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 <class _Tp>
+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 <class _CharT, class _Traits>
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 <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
-template <class T> void return_temporary_buffer(T* p) noexcept;
+template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept; // deprecated in C++17, removed in C++20
+template <class T> void return_temporary_buffer(T* p) noexcept; // deprecated in C++17, removed in C++20
template <class T> T* addressof(T& r) noexcept;
template <class T> 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 <exception>
#include <new>
#include <typeinfo>
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 <memory> 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<int> 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 <exception>
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
// <memory>
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 @@
// <memory>
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
// template <class T>
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" <de34 at live.cn>
Date: Thu, 1 Aug 2024 22:33:41 +0800
Subject: [PATCH 2/5] 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" <de34 at live.cn>
Date: Sat, 3 Aug 2024 23:19:17 +0800
Subject: [PATCH 3/5] 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 <https://https://libcxx.llvm.org/Status/SpecialMath.html>`_.
.. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` 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 <https://llvm.org/PR45368>`__.
- .. [#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 <class _CharT, class _Traits>
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 <exception>
#include <new>
#include <typeinfo>
>From 2841f7201870e8472986f70d59123ac8268e5882 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 23:55:57 +0800
Subject: [PATCH 4/5] 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 <exception>
>From 5268aa909b81e3adc765df3748f17fab91823f0a Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 5 Aug 2024 01:20:47 +0800
Subject: [PATCH 5/5] 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 <new>
@@ -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<value_type*, ptrdiff_t> __buf = std::__get_temporary_buffer<value_type>(__buf_size);
- unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
+ __scoped_temporary_buffer<value_type> __scoped_buf(__buf_size);
+ __temporary_allocation_result<value_type> __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 <class _BidirectionalIterator, class _Compare>
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<value_type> __scoped_buf;
pair<value_type*, ptrdiff_t> __p(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len >= __alloc_limit) {
- __p = std::__get_temporary_buffer<value_type>(__len);
- __h.reset(__p.first);
+ __scoped_buf.__try_allocate(__len);
+ __temporary_allocation_result<value_type> __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<value_type> __scoped_buf;
pair<value_type*, ptrdiff_t> __p(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len >= __alloc_limit) {
- __p = std::__get_temporary_buffer<value_type>(__len);
- __h.reset(__p.first);
+ __scoped_buf.__try_allocate(__len);
+ __temporary_allocation_result<value_type> __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<value_type> __scoped_buf;
pair<value_type*, ptrdiff_t> __buf(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
- __buf = std::__get_temporary_buffer<value_type>(__len);
- __h.reset(__buf.first);
+ __scoped_buf.__try_allocate(__len);
+ __temporary_allocation_result<value_type> __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 <cstddef>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __temporary_allocation_result {
+ _Tp* __ptr;
+ ptrdiff_t __count;
+};
+
+template <class _Tp>
+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 <cstddef>
#include <new>
@@ -19,65 +20,26 @@
# pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp>
-_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 <class _Tp>
- _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 <class _Tp>
_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 <class _Tp>
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",
More information about the llvm-commits
mailing list