diff --git a/stl/inc/xmemory b/stl/inc/xmemory index c65ccedac9c..013fb5b297b 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -833,6 +833,7 @@ public: } _NODISCARD _CONSTEXPR20 __declspec(allocator) _Ty* allocate(_CRT_GUARDOVERFLOW const size_t _Count) { + static_assert(sizeof(value_type) > 0, "value_type must be complete before calling allocate."); return static_cast<_Ty*>(_Allocate<_New_alignof<_Ty>>(_Get_size_of_n(_Count))); } @@ -866,6 +867,7 @@ public: static constexpr size_t _Minimum_allocation_alignment = _Asan_granularity; }; +#if _HAS_DEPRECATED_ALLOCATOR_VOID || _HAS_DEPRECATED_ALLOCATOR_MEMBERS template <> class allocator { public: @@ -873,21 +875,22 @@ public: #if _HAS_DEPRECATED_ALLOCATOR_MEMBERS _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS typedef void* pointer; _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS typedef const void* const_pointer; + + template + struct _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS rebind { + using other = allocator<_Other>; + }; #endif // _HAS_DEPRECATED_ALLOCATOR_MEMBERS +#if _HAS_CXX20 using size_type = size_t; using difference_type = ptrdiff_t; using propagate_on_container_move_assignment = true_type; using is_always_equal _CXX20_DEPRECATE_IS_ALWAYS_EQUAL = true_type; - -#if _HAS_DEPRECATED_ALLOCATOR_MEMBERS - template - struct _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS rebind { - using other = allocator<_Other>; - }; -#endif // _HAS_DEPRECATED_ALLOCATOR_MEMBERS +#endif // _HAS_CXX20 }; +#endif // _HAS_DEPRECATED_ALLOCATOR_VOID || _HAS_DEPRECATED_ALLOCATOR_MEMBERS template _NODISCARD _CONSTEXPR20 bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 088b22c121d..40d7a928a07 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1197,6 +1197,10 @@ #define _HAS_DEPRECATED_ALLOCATOR_MEMBERS (_HAS_FEATURES_REMOVED_IN_CXX20) #endif // _HAS_DEPRECATED_ALLOCATOR_MEMBERS +#ifndef _HAS_DEPRECATED_ALLOCATOR_VOID +#define _HAS_DEPRECATED_ALLOCATOR_VOID (_HAS_FEATURES_REMOVED_IN_CXX20) +#endif // _HAS_DEPRECATED_ALLOCATOR_VOID + #ifndef _HAS_DEPRECATED_IS_LITERAL_TYPE #define _HAS_DEPRECATED_IS_LITERAL_TYPE (_HAS_FEATURES_REMOVED_IN_CXX20) #endif // _HAS_DEPRECATED_IS_LITERAL_TYPE diff --git a/tests/std/test.lst b/tests/std/test.lst index d2b6b5e45b9..4b9f00d4d18 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -164,6 +164,7 @@ tests\GH_000431_lex_compare_family tests\GH_000431_lex_compare_memcmp_classify tests\GH_000442_random_subtract_with_carry_engine_io tests\GH_000457_system_error_message +tests\GH_000527_remove_allocator_void tests\GH_000545_include_compare tests\GH_000625_vector_bool_optimization tests\GH_000685_condition_variable_any diff --git a/tests/std/tests/GH_000527_remove_allocator_void/env.lst b/tests/std/tests/GH_000527_remove_allocator_void/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_000527_remove_allocator_void/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_000527_remove_allocator_void/test.compile.pass.cpp b/tests/std/tests/GH_000527_remove_allocator_void/test.compile.pass.cpp new file mode 100644 index 00000000000..f1cf4c2c0c0 --- /dev/null +++ b/tests/std/tests/GH_000527_remove_allocator_void/test.compile.pass.cpp @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#define _SILENCE_CXX20_IS_ALWAYS_EQUAL_DEPRECATION_WARNING + +#include +#include +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +using namespace std; + +template +constexpr bool has_member_size_type = false; + +template +constexpr bool has_member_size_type> = true; + +template +constexpr bool has_member_difference_type = false; + +template +constexpr bool has_member_difference_type> = true; + +template +constexpr bool has_member_pocma = false; + +template +constexpr bool has_member_pocma> = true; + +template +constexpr bool has_member_is_always_equal = false; + +template +constexpr bool has_member_is_always_equal> = true; + +template +constexpr bool can_allocate = false; + +template +constexpr bool can_allocate().allocate(size_t{}))>> = true; + +STATIC_ASSERT(has_member_size_type>); +STATIC_ASSERT(has_member_difference_type>); +STATIC_ASSERT(has_member_pocma>); +STATIC_ASSERT(has_member_is_always_equal>); +STATIC_ASSERT(can_allocate>); +STATIC_ASSERT(is_convertible_v, allocator>); + +#if _HAS_CXX20 +constexpr bool has_cxx20 = true; +#else +constexpr bool has_cxx20 = false; +#endif + +STATIC_ASSERT(has_cxx20 == has_member_size_type>); +STATIC_ASSERT(has_cxx20 == has_member_difference_type>); +STATIC_ASSERT(has_cxx20 == has_member_pocma>); +STATIC_ASSERT(has_cxx20 == has_member_is_always_equal>); +STATIC_ASSERT(has_cxx20 == can_allocate>); +STATIC_ASSERT(has_cxx20 == is_convertible_v, allocator>); + +int main() {} // COMPILE-ONLY