[llvm-branch-commits] [libcxx] a00290e - [libc++] Fix allocate_shared when used with an explicitly convertible allocator
Louis Dionne via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 15 08:54:23 PST 2020
Author: Louis Dionne
Date: 2020-12-15T11:50:06-05:00
New Revision: a00290ed10a6b4e9f6e9be44ceec367562f270c6
URL: https://github.com/llvm/llvm-project/commit/a00290ed10a6b4e9f6e9be44ceec367562f270c6
DIFF: https://github.com/llvm/llvm-project/commit/a00290ed10a6b4e9f6e9be44ceec367562f270c6.diff
LOG: [libc++] Fix allocate_shared when used with an explicitly convertible allocator
When the allocator is only explicitly convertible from other specializations
of itself, the new version of std::allocate_shared would not work because
it would try to do an implicit conversion. This patch fixes the problem
and adds a test so that we don't fall into the same trap in the future.
Added:
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp
Modified:
libcxx/include/__memory/utilities.h
Removed:
################################################################################
diff --git a/libcxx/include/__memory/utilities.h b/libcxx/include/__memory/utilities.h
index ccbfbe78966c..aac3d11cab57 100644
--- a/libcxx/include/__memory/utilities.h
+++ b/libcxx/include/__memory/utilities.h
@@ -48,8 +48,9 @@ struct __allocation_guard {
using _Pointer = typename allocator_traits<_Alloc>::pointer;
using _Size = typename allocator_traits<_Alloc>::size_type;
+ template<class _AllocT> // we perform the allocator conversion inside the constructor
_LIBCPP_HIDE_FROM_ABI
- explicit __allocation_guard(_Alloc __alloc, _Size __n)
+ explicit __allocation_guard(_AllocT __alloc, _Size __n)
: __alloc_(_VSTD::move(__alloc))
, __n_(__n)
, __ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp
new file mode 100644
index 000000000000..446daa1ec9f2
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that std::allocate_shared works with an allocator type that is
+// only explicitly convertible from another specialization of itself.
+
+#include <cassert>
+#include <cstddef>
+#include <memory>
+
+template <class T>
+struct ExplicitAllocator {
+ ExplicitAllocator() = default;
+ template <class U>
+ explicit ExplicitAllocator(ExplicitAllocator<U>) { }
+
+ using value_type = T;
+ T* allocate(std::size_t n) { return std::allocator<T>().allocate(n); }
+ void deallocate(T* ptr, std::size_t n) { return std::allocator<T>().deallocate(ptr, n); }
+};
+
+int main(int, char**) {
+ std::shared_ptr<int> ptr = std::allocate_shared<int>(ExplicitAllocator<int>(), 0);
+ (void)ptr;
+
+ return 0;
+}
More information about the llvm-branch-commits
mailing list