#include <memory> int main() { std::allocator<void> a; } alloc.C:5:8: warning: 'allocator<void>' is deprecated [-Wdeprecated-declarations] std::allocator<void> a; ^ /usr/bin/../include/c++/v1/memory:725:28: note: 'allocator<void>' has been explicitly marked deprecated here class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void> ^ /usr/bin/../include/c++/v1/__config:1035:39: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED ^ /usr/bin/../include/c++/v1/__config:1012:48: note: expanded from macro '_LIBCPP_DEPRECATED' # define _LIBCPP_DEPRECATED __attribute__ ((deprecated)) ^ This warning is misleading and unhelpful. It's true that the explicit specialization is deprecated in C++17 and gone in C++20, but that doesn't mean users can't use std::allocator<void> in C++20. It just means that doing so uses the primary template. It's perfectly fine to use std::allocator<void> in C++17 in limited ways (e.g. you can't use it to allocate, obviously) and it's perfectly fine to use it in the same ways in C++20. Telling users it's deprecated is totally unhelpful, because they don't need to stop using it, but they can't do anything about the warnings except to stop using it. What purpose do the warnings serve? What do you expect users to do if they get that warning? Why should they change their code, when there's nothing wrong with it? Please revert the additions of the deprecated attributes here.
For added fun, you have a potential ABI break: #include <memory> struct A : std::allocator<void> { }; static_assert( std::is_trivially_default_constructible<A>::value, "" ); static_assert( std::is_trivial<A>::value, "" ); This passes in C++17 and earlier, but not in C++20: a.C:5:1: error: static_assert failed due to requirement 'std::is_trivially_default_constructible<A>::value' "" static_assert( std::is_trivially_default_constructible<A>::value, "" ); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.C:6:1: error: static_assert failed due to requirement 'std::is_trivial<A>::value' "" static_assert( std::is_trivial<A>::value, "" ); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ Your primary template for std::allocator has a non-trivial default constructor (for C++03 compat, just like GCC's one does) and so when allocator<void> uses the primary template, it also has a non-trivial default ctor. In C++17 the explicit specialization for allocator<void> has a trivial default ctor. I don't know if you care about this case.
(In reply to Jonathan Wakely from comment #0) > This warning is misleading and unhelpful. It's true that the explicit > specialization is deprecated in C++17 and gone in C++20, but that doesn't > mean users can't use std::allocator<void> in C++20. It just means that doing > so uses the primary template. This was even called out in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html#3.9 "Removing the explicit specialization, per the proposed resolution below, should no impact on that, as the primary template will now provide the correct behavior." The intention is that allocator<void> continues to be usable by programs, all that changes is how the library defines it. And so giving users a diagnostic is wrong.
You're right, but for our defence, https://wg21.link/p0174#2.2 did deprecate the specialization, and I'm not seeing any discussion saying something like "but oh, users should still be able to use it". The intent appears to be pretty unclear if you read only that paper, and you actually need to read the fine print in wg21.link/p0619r4#3.9 to know the intent. Am I missing something or that's messed up?
> For added fun, you have a potential ABI break: I think that is unlikely to bite anyone.
https://reviews.llvm.org/D104323
I'm also trying to backport this to LLVM 12.0.1 because I think this is a pretty vexing issue: https://reviews.llvm.org/D104324
commit 87784cc6fb3453a17e0e7826b943a1d93cbfeccf Author: Louis Dionne <ldionne.2@gmail.com> Date: Tue Jun 15 16:08:38 2021 -0400 [libc++] Undeprecate the std::allocator<void> specialization While the std::allocator<void> specialization was deprecated by https://wg21.link/p0174#2.2, the *use* of std::allocator<void> by users was not. The intent was that std::allocator<void> could still be used in C++17 and C++20, but starting with C++20 (with the removal of the specialization), std::allocator<void> would use the primary template. That intent was called out in wg21.link/p0619r4#3.9. As a result of this patch, _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS will also not control whether the explicit specialization is provided or not. It shouldn't matter, since in C++20, one can simply use the primary template. Fixes http://llvm.org/PR50299 Differential Revision: https://reviews.llvm.org/D104323
I also created a patch for fixing the triviality difference between C++20 and previous standard modes at https://reviews.llvm.org/D104398.
The fix does not apply cleanly, could someone backport this and push a branch to their local github fork?
(In reply to Tom Stellard from comment #9) > The fix does not apply cleanly, could someone backport this and push a > branch to their local github fork? This has already been merged to `release/12.x`: commit e7dac564cd0ed9dee74ef972c46622743d90915d Author: Louis Dionne <ldionne.2@gmail.com> Date: Tue Jun 15 17:55:27 2021 -0400 [🍒][libc++] Un-deprecate std::allocator<void> This is a cherry-pick of 87784cc6fb3453a17e0e78 on 'main' for backporting to LLVM 12. Differential Revision: https://reviews.llvm.org/D104324