From d96fac1530d6e54376c25e70b78adeea27d49a52 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 19 Jul 2023 13:38:34 -0700 Subject: [PATCH 1/2] Detect allocate_at_least with a concept ... to avoid a C1XX bug in the non-requires-expression detection. Fixes VSO-1852860. --- stl/inc/xmemory | 5 ++++ .../GH_003570_allocate_at_least/test.cpp | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 0260da13c88..952edc7d86f 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -471,12 +471,17 @@ struct _Is_default_allocator, void_t::_Fr : is_same::_From_primary, allocator<_Ty>>::type {}; #if _HAS_CXX23 +#ifdef __cpp_lib_concepts // TRANSITION, GH-395 +template +concept _Has_member_allocate_at_least = requires(_Alloc& _Al, const _SizeTy& _Count) { _Al.allocate_at_least(_Count); }; +#else // ^^^ no workaround / workaround vvv template inline constexpr bool _Has_member_allocate_at_least = false; template inline constexpr bool _Has_member_allocate_at_least<_Alloc, _SizeTy, void_t().allocate_at_least(_STD declval()))>> = true; +#endif // __cpp_lib_concepts #endif // _HAS_CXX23 template diff --git a/tests/std/tests/GH_003570_allocate_at_least/test.cpp b/tests/std/tests/GH_003570_allocate_at_least/test.cpp index 05a5f45cf52..1121d7e8fd5 100644 --- a/tests/std/tests/GH_003570_allocate_at_least/test.cpp +++ b/tests/std/tests/GH_003570_allocate_at_least/test.cpp @@ -122,6 +122,31 @@ void test_inheriting_allocator() { assert(accumulate(vec.begin(), vec.end(), 0, plus<>{}) == 36); } +// Also test VSO-1852860, in which we incorrectly tried to use allocate_at_least from an inaccessible std::allocator +// base due to an MSVC bug. +template +struct less_icky_allocator : private allocator { + using value_type = T; + + less_icky_allocator() = default; + template + less_icky_allocator(const less_icky_allocator&) {} + + T* allocate(size_t n) { + return allocator::allocate(n); + } + + void deallocate(T* ptr, size_t n) { + return allocator::deallocate(ptr, n); + } + + template + bool operator==(const less_icky_allocator&) const { + return true; + } +}; +static_assert(!std::_Should_allocate_at_least>); + int main() { test_deque(); test_container, signalling_allocator>>(); From efa59967ae7904ef558368411423b09b8bd069e5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 19 Jul 2023 13:55:16 -0700 Subject: [PATCH 2/2] Code review feedback. --- stl/inc/xmemory | 2 +- tests/std/tests/GH_003570_allocate_at_least/test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 952edc7d86f..541258019c2 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -472,7 +472,7 @@ struct _Is_default_allocator, void_t::_Fr #if _HAS_CXX23 #ifdef __cpp_lib_concepts // TRANSITION, GH-395 -template +template concept _Has_member_allocate_at_least = requires(_Alloc& _Al, const _SizeTy& _Count) { _Al.allocate_at_least(_Count); }; #else // ^^^ no workaround / workaround vvv template diff --git a/tests/std/tests/GH_003570_allocate_at_least/test.cpp b/tests/std/tests/GH_003570_allocate_at_least/test.cpp index 1121d7e8fd5..1814ff4e2bd 100644 --- a/tests/std/tests/GH_003570_allocate_at_least/test.cpp +++ b/tests/std/tests/GH_003570_allocate_at_least/test.cpp @@ -122,7 +122,7 @@ void test_inheriting_allocator() { assert(accumulate(vec.begin(), vec.end(), 0, plus<>{}) == 36); } -// Also test VSO-1852860, in which we incorrectly tried to use allocate_at_least from an inaccessible std::allocator +// Also test GH-3890, in which we incorrectly tried to use allocate_at_least from an inaccessible std::allocator // base due to an MSVC bug. template struct less_icky_allocator : private allocator {