This commit is a step towards making it easier to add support for arrays
in allocate_shared. Adding support for arrays will require writing multiple
functions, and the current complexity of writing allocate_shared is
prohibitive for understanding.
Details
- Reviewers
ldionne - Group Reviewers
Restricted Project - Commits
- rG19d57b5c42b4: [libc++] Refactor allocate_shared to use an allocation guard
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This change appears to have dropped a constructor, or maybe two. I'm not familiar enough with all the requirements to know if that is correct or not. Here is a somewhat redacted version of the errors I get building a private application.
In module 'xyz':
.../include/c++/v1/memory:3341:48: error: no matching constructor for initialization of 'allocation_guard<_Foo>' (aka 'allocation_guard<Allocator<std::u::shared_ptr_emplace<Bar::Bat, Baz::Ball::Allocator<Bar::Bat>>>>')
__allocation_guard<_Foo> __guard(__a, 1); ^ ~~~~~~
source.cc:57:15: note: in instantiation of function template specialization 'std::__u::allocate_shared<Bar::Bat, Baz::Ball::Allocator<Bar::Bat>, Bar::Bat::ConstructorToken, std::string_view &, Bar::BatOptions &, void>' requested here
return std::allocate_shared<MemoryTracker>(Alloc(), ConstructorToken(), name, ^
.../include/c++/v1/__memory/utilities.h:52:14: note: candidate constructor not viable: no known conversion from 'const Allocator<Bar::Bat>' to 'Allocator<std::u::shared_ptr_emplace<Bar::Bat, Baz::Ball::Allocator<Bar::Bat>>>' for 1st argument
explicit __allocation_guard(_Alloc __alloc, _Size __n) ^
.../include/c++/v1/__memory/utilities.h:47:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct __allocation_guard {
^
In module 'xyz':
.../include/c++/v1/memory:3341:48: error: no matching constructor for initialization of 'allocation_guard<_Foo>' (aka 'allocation_guard<Allocator<std::u::shared_ptr_emplace<Bar::Bat, Baz::Ball::Allocator<Bar::Bat>>>>')
__allocation_guard<_Foo> __guard(__a, 1); ^ ~~~~~~
source.cc:229:16: note: in instantiation of function template specialization 'std::__u::allocate_shared<Bar::Bat, Baz::Ball::Allocator<Bar::Bat>, Bar::Bat::ConstructorToken, char const (&)[7], Bar::BatOptions, void>' requested here
std::allocate_shared<MemoryTracker>( ^
.../include/c++/v1/__memory/utilities.h:52:14: note: candidate constructor not viable: no known conversion from 'const Allocator<Bar::Bat>' to 'Allocator<std::u::shared_ptr_emplace<Bar::Bat, Baz::Ball::Allocator<Bar::Bat>>>' for 1st argument
explicit __allocation_guard(_Alloc __alloc, _Size __n) ^
.../include/c++/v1/__memory/utilities.h:47:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct __allocation_guard {
Is it possible that your custom Allocator has its converting copy constructor (from other specializations of Allocator) marked as explicit? We don't seem to have a test for that, I'll add one and fix this, but please confirm that it's the case.
Ok, that was it. Fixed by:
commit a00290ed10a6b4e9f6e9be44ceec367562f270c6 (HEAD -> main, github-llvm/main) Author: Louis Dionne <ldionne.2@gmail.com> Date: Tue Dec 15 11:45:53 2020 -0500 [libc++] Fix allocate_shared when used with an explicitly convertible allocator When the allocator is only explicitly convertible from other specializations of itself, the new version of std::allocate_shared would not work because it would try to do an implicit conversion. This patch fixes the problem and adds a test so that we don't fall into the same trap in the future.