[libcxx-commits] [libcxx] [libc++] Fix ambiguity when using std::scoped_allocator constructor (PR #80020)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 30 07:34:24 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Louis Dionne (ldionne)
<details>
<summary>Changes</summary>
As a drive-by change, also fix a name that wasn't uglified in the code and add a test for that.
Fixes #<!-- -->78754
---
Full diff: https://github.com/llvm/llvm-project/pull/80020.diff
3 Files Affected:
- (modified) libcxx/include/scoped_allocator (+16-12)
- (modified) libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp (+13-1)
- (added) libcxx/test/std/utilities/allocator.adaptor/base-is-uglified.compile.pass.cpp (+27)
``````````diff
diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator
index 6078906e92248..2d56ae785e5e4 100644
--- a/libcxx/include/scoped_allocator
+++ b/libcxx/include/scoped_allocator
@@ -197,6 +197,8 @@ struct __get_is_always_equal<_A0, _Allocs...> {
static const bool value = allocator_traits<_A0>::is_always_equal::value && __get_is_always_equal<_Allocs...>::value;
};
+struct __chained_ctor_tag {};
+
template <class... _Allocs>
class __scoped_allocator_storage;
@@ -249,6 +251,7 @@ protected:
scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> _LIBCPP_HIDE_FROM_ABI
select_on_container_copy_construction() const _NOEXCEPT {
return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>(
+ __chained_ctor_tag(),
allocator_traits<outer_allocator_type>::select_on_container_copy_construction(outer_allocator()),
allocator_traits<inner_allocator_type>::select_on_container_copy_construction(inner_allocator()));
}
@@ -334,12 +337,12 @@ struct __outermost<_Alloc, true> {
template <class _OuterAlloc, class... _InnerAllocs>
class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
: public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> {
- typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
+ typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> _Base;
typedef allocator_traits<_OuterAlloc> _OuterTraits;
public:
typedef _OuterAlloc outer_allocator_type;
- typedef typename base::inner_allocator_type inner_allocator_type;
+ typedef typename _Base::inner_allocator_type inner_allocator_type;
typedef typename _OuterTraits::size_type size_type;
typedef typename _OuterTraits::difference_type difference_type;
typedef typename _OuterTraits::pointer pointer;
@@ -365,29 +368,29 @@ public:
template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
scoped_allocator_adaptor(_OuterA2&& __outer_alloc, const _InnerAllocs&... __inner_allocs) _NOEXCEPT
- : base(std::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
+ : _Base(std::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
// scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
scoped_allocator_adaptor(const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
- : base(__other) {}
+ : _Base(__other) {}
template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
scoped_allocator_adaptor(scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
- : base(std::move(__other)) {}
+ : _Base(std::move(__other)) {}
// scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
// scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
// ~scoped_allocator_adaptor() = default;
- _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return base::inner_allocator(); }
+ _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return _Base::inner_allocator(); }
_LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT {
- return base::inner_allocator();
+ return _Base::inner_allocator();
}
- _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { return base::outer_allocator(); }
+ _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { return _Base::outer_allocator(); }
_LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT {
- return base::outer_allocator();
+ return _Base::outer_allocator();
}
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI pointer allocate(size_type __n) {
@@ -472,13 +475,14 @@ public:
}
_LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT {
- return base::select_on_container_copy_construction();
+ return _Base::select_on_container_copy_construction();
}
private:
template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor(_OuterA2&& __o, const inner_allocator_type& __i) _NOEXCEPT
- : base(std::forward<_OuterA2>(__o), __i) {}
+ _LIBCPP_HIDE_FROM_ABI
+ scoped_allocator_adaptor(__chained_ctor_tag, _OuterA2&& __o, const inner_allocator_type& __i) _NOEXCEPT
+ : _Base(std::forward<_OuterA2>(__o), __i) {}
template <class _Tp, class... _Args>
_LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 0>, _Tp* __p, _Args&&... __args) {
diff --git a/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp b/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
index a752dfd029eff..91dd13e4cd354 100644
--- a/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
+++ b/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
@@ -17,8 +17,9 @@
// scoped_allocator_adaptor(OuterA2&& outerAlloc,
// const InnerAllocs& ...innerAllocs);
-#include <scoped_allocator>
#include <cassert>
+#include <memory_resource>
+#include <scoped_allocator>
#include "test_macros.h"
#include "allocators.h"
@@ -111,6 +112,17 @@ int main(int, char**) {
!std::is_convertible< std::scoped_allocator_adaptor<A1<int>>, std::scoped_allocator_adaptor<A2<int>>>::value,
"");
}
+ {
+ // https://github.com/llvm/llvm-project/issues/78754
+ using PA = std::pmr::polymorphic_allocator<int>;
+ std::pmr::monotonic_buffer_resource mr1;
+ std::pmr::monotonic_buffer_resource mr2;
+
+ using A = std::scoped_allocator_adaptor<PA, PA>;
+ A a(&mr1, &mr2);
+ assert(a.outer_allocator().resource() == &mr1);
+ assert(a.inner_allocator().resource() == &mr2);
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/allocator.adaptor/base-is-uglified.compile.pass.cpp b/libcxx/test/std/utilities/allocator.adaptor/base-is-uglified.compile.pass.cpp
new file mode 100644
index 0000000000000..af2171b0e234c
--- /dev/null
+++ b/libcxx/test/std/utilities/allocator.adaptor/base-is-uglified.compile.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <memory>
+
+// This test ensures that we don't use a non-uglified name 'base' in the
+// implementation of scoped_allcoator_adaptor.
+//
+// See https://github.com/llvm/llvm-project/issues/78754.
+
+#include <memory>
+#include <scoped_allocator>
+
+using ScopedAlloc = std::scoped_allocator_adaptor<std::allocator<int>, std::allocator<int>>;
+struct MyBase {
+ using base = MyBase;
+};
+struct MyDerived : ScopedAlloc, MyBase {};
+
+using T = MyDerived::base; // Should be well-formed
``````````
</details>
https://github.com/llvm/llvm-project/pull/80020
More information about the libcxx-commits
mailing list