Though the implicit copy constructor of BumpPtrAllocatorImpl is deleted
because of the presence of a user-defined move constructor, the
perfect-forwarding constructor will still match for lvalue reference of
BumpPtrAllocatorImpl, silently "copying" a BumpPtrAllocatorImpl
(actually just copy-constructing an underlying AllocatorT and
blank-constructing a BumpPtrAllocatorImpl).
This patch explicitly deletes the problematic specialization of the
forwarding constructor.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
I'm having trouble to find an appropriate place and approach to test this. Any ideas?
llvm/include/llvm/Support/Allocator.h | ||
---|---|---|
85 | This isn't using the right template parameters. I'd suggest just BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) = delete;. Or I guess you could do something like template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold, size_t GrowthDelay> BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold, GrowthDelay> &) = delete;. |
I was curious if the standard specified anything about allocators being copy-constructable. I didn't actually check the standard itself, but cppreference seems to say so: https://en.cppreference.com/w/cpp/named_req/Allocator
Every Allocator also satisfies CopyConstructible.
llvm/include/llvm/Support/Allocator.h | ||
---|---|---|
85 | Ahh makes sense.
IIUC this would just delete the case where BumpPtrAllocatorImpl with the same template arguments right? I guess I should go with the full thing. Also I need to drop the const apparently because otherwise the perfect-forwarding will always be a better match. |
Huh. Then I guess the "fix" would be to actually provide correct copy-constructing behaviors? Currently in this case, the implicit copy-constructor (BumpAllocatorImpl(const BumpAllocatorImpl &)) is deleted, and the forwarding constructor provides a match for BumpAllocatorImpl(BumpAllocatorImpl &) but does nothing.
llvm/unittests/Support/AllocatorTest.cpp | ||
---|---|---|
49–58 | Perhaps this could be done with a static_assert in the header - no need for a test case/runtime expect of the value? |
This isn't using the right template parameters. I'd suggest just BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) = delete;. Or I guess you could do something like template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold, size_t GrowthDelay> BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold, GrowthDelay> &) = delete;.