[libcxx-commits] [libcxx] [libc++] Make sure LWG2070 is implemented as a DR (PR #65998)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 13 12:54:05 PDT 2023
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/65998:
>From 29fa1bc2fedb629c5387f311e59b3f12e3e07643 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 11 Sep 2023 14:56:33 -0400
Subject: [PATCH] [libc++] Make sure LWG2070 is implemented as a DR
When we implemented C++20's P0674R1, we didn't enable the part of P0674R1
that was resolving LWG2070 as a DR. This patch fixes that and makes sure
that we consistently go through the allocator when constructing and
destroying the underlying object in std::allocate_shared.
Fixes #54365.
---
libcxx/include/__memory/shared_ptr.h | 50 ++++++++++---------
...s.cpp => allocate_shared.lwg2070.pass.cpp} | 8 +--
.../allocate_shared.pass.cpp | 23 ---------
3 files changed, 31 insertions(+), 50 deletions(-)
rename libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/{allocate_shared_construct.pass.cpp => allocate_shared.lwg2070.pass.cpp} (92%)
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 845882ad31134d2..6be2f22184590ae 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -285,23 +285,23 @@ template <class _Tp, class _Alloc>
struct __shared_ptr_emplace
: __shared_weak_count
{
- template<class ..._Args>
+ template <class... _Args, class _Allocator = _Alloc, __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...)
+ : __storage_(_VSTD::move(__a))
+ {
+ static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
+ ::new ((void*)__get_elem()) _Tp;
+ }
+
+ template <class... _Args, class _Allocator = _Alloc, __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
: __storage_(_VSTD::move(__a))
{
-#if _LIBCPP_STD_VER >= 20
- if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
- static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
- ::new ((void*)__get_elem()) _Tp;
- } else {
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
- }
-#else
- ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
-#endif
+ using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+ _TpAlloc __tmp(*__get_alloc());
+ allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
}
_LIBCPP_HIDE_FROM_ABI
@@ -311,18 +311,20 @@ struct __shared_ptr_emplace
_Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
private:
- _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
-#if _LIBCPP_STD_VER >= 20
- if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
- __get_elem()->~_Tp();
- } else {
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
- }
-#else
+ template <class _Allocator = _Alloc, __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
__get_elem()->~_Tp();
-#endif
+ }
+
+ template <class _Allocator = _Alloc, __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
+ using _TpAlloc = typename __allocator_traits_rebind<_Allocator, _Tp>::type;
+ _TpAlloc __tmp(*__get_alloc());
+ allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+ }
+
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
+ __on_zero_shared_impl();
}
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_construct.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.lwg2070.pass.cpp
similarity index 92%
rename from libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_construct.pass.cpp
rename to libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.lwg2070.pass.cpp
index 4281cc1aa9e0db8..89b6cb6c11a361f 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_construct.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.lwg2070.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++03, c++11, c++14
// <memory>
@@ -15,8 +15,10 @@
// template<class T, class A, class... Args>
// shared_ptr<T> allocate_shared(const A& a, Args&&... args);
-// This test checks that allocator_traits::construct is used in allocate_shared
-// as requested in C++20 (via P0674R1).
+// This test checks that allocator_traits::construct and allocator_traits::destroy
+// are used in allocate_shared as requested for the resolution of LWG2070. Note
+// that LWG2070 was resolved by P0674R1 (which is a C++20 paper), but we implement
+// LWG issue resolutions as DRs per our policy.
#include "test_macros.h"
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
index ac7a9913b0e9182..341a442c90a1674 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
@@ -90,22 +90,6 @@ struct Three
int Three::count = 0;
-template<class T>
-struct AllocNoConstruct : std::allocator<T>
-{
- AllocNoConstruct() = default;
-
- template <class T1>
- AllocNoConstruct(AllocNoConstruct<T1>) {}
-
- template <class T1>
- struct rebind {
- typedef AllocNoConstruct<T1> other;
- };
-
- void construct(void*) { assert(false); }
-};
-
template <class Alloc>
void test()
{
@@ -182,12 +166,5 @@ int main(int, char**)
assert(p2 != nullptr);
}
- // Test that we don't call construct before C++20.
-#if TEST_STD_VER < 20
- {
- (void)std::allocate_shared<int>(AllocNoConstruct<int>());
- }
-#endif // TEST_STD_VER < 20
-
return 0;
}
More information about the libcxx-commits
mailing list