LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 50299 - Bogus warnings: warning: 'allocator<void>' is deprecated
Summary: Bogus warnings: warning: 'allocator<void>' is deprecated
Status: RESOLVED FIXED
Alias: None
Product: libc++
Classification: Unclassified
Component: All Bugs (show other bugs)
Version: 11.0
Hardware: PC Linux
: P normal
Assignee: Louis Dionne
URL:
Keywords:
Depends on:
Blocks: release-12.0.1
  Show dependency tree
 
Reported: 2021-05-11 05:47 PDT by Jonathan Wakely
Modified: 2021-06-23 09:31 PDT (History)
7 users (show)

See Also:
Fixed By Commit(s): 87784cc6fb3453a17e0e7826b943a1d93cbfeccf e7dac564cd0ed9dee74ef972c46622743d90915d


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2021-05-11 05:47:34 PDT
#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.
Comment 1 Jonathan Wakely 2021-05-11 06:34:24 PDT
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.
Comment 2 Jonathan Wakely 2021-05-11 07:14:46 PDT
(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.
Comment 3 Louis Dionne 2021-06-15 13:21:24 PDT
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?
Comment 4 Louis Dionne 2021-06-15 13:25:33 PDT
> For added fun, you have a potential ABI break:

I think that is unlikely to bite anyone.
Comment 5 Louis Dionne 2021-06-15 14:31:17 PDT
https://reviews.llvm.org/D104323
Comment 6 Louis Dionne 2021-06-15 14:58:00 PDT
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
Comment 7 Louis Dionne 2021-06-16 06:55:28 PDT
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
Comment 8 Louis Dionne 2021-06-16 10:09:06 PDT
I also created a patch for fixing the triviality difference between C++20 and previous standard modes at https://reviews.llvm.org/D104398.
Comment 9 Tom Stellard 2021-06-22 21:55:44 PDT
The fix does not apply cleanly, could someone backport this and push a branch to their local github fork?
Comment 10 Louis Dionne 2021-06-23 08:39:07 PDT
(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