diff --git a/llvm/include/llvm/Support/Allocator.h b/llvm/include/llvm/Support/Allocator.h --- a/llvm/include/llvm/Support/Allocator.h +++ b/llvm/include/llvm/Support/Allocator.h @@ -79,6 +79,11 @@ BumpPtrAllocatorImpl(T &&Allocator) : AllocatorT(std::forward(Allocator)) {} + // BumpPtrAllocator shouldn't be copyable. Explicitly delete this + // specialization of the perfect-forwarding constructor above. + template + BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &) = delete; + // Manually implement a move constructor as we must clear the old allocator's // slabs as a matter of correctness. BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old) diff --git a/llvm/unittests/Support/AllocatorTest.cpp b/llvm/unittests/Support/AllocatorTest.cpp --- a/llvm/unittests/Support/AllocatorTest.cpp +++ b/llvm/unittests/Support/AllocatorTest.cpp @@ -9,6 +9,7 @@ #include "llvm/Support/Allocator.h" #include "gtest/gtest.h" #include +#include using namespace llvm; @@ -45,6 +46,16 @@ EXPECT_EQ(1U, Alloc.GetNumSlabs()); } +TEST(AllocatorTest, NoCopy) { + constexpr bool CopyConstructible = + std::is_copy_constructible::value; + EXPECT_FALSE(CopyConstructible); + + constexpr bool NonConstLRefConstructible = + std::is_constructible::value; + EXPECT_FALSE(NonConstLRefConstructible); +} + // Allocate enough bytes to create three slabs. TEST(AllocatorTest, ThreeSlabs) { BumpPtrAllocator Alloc;