From 07f42cd526c51131d1748e3be8683d24c396d9eb Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 4 Aug 2015 15:52:56 +0000 Subject: [PATCH] [ArrayRef] Make copy use std::uninitialized_copy. std::copy does not work for non-trivially copyable classes when we're copying into uninitialized memory. llvm-svn: 243995 --- llvm/include/llvm/ADT/ArrayRef.h | 2 +- llvm/unittests/ADT/ArrayRefTest.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h index f6cc4f4..e806330 100644 --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/include/llvm/ADT/ArrayRef.h @@ -148,7 +148,7 @@ namespace llvm { // copy - Allocate copy in Allocator and return ArrayRef to it. template ArrayRef copy(Allocator &A) { T *Buff = A.template Allocate(Length); - std::copy(begin(), end(), Buff); + std::uninitialized_copy(begin(), end(), Buff); return ArrayRef(Buff, Length); } diff --git a/llvm/unittests/ADT/ArrayRefTest.cpp b/llvm/unittests/ADT/ArrayRefTest.cpp index 9ad32d5..0640241 100644 --- a/llvm/unittests/ADT/ArrayRefTest.cpp +++ b/llvm/unittests/ADT/ArrayRefTest.cpp @@ -31,7 +31,7 @@ static_assert( !std::is_convertible, ArrayRef>::value, "Removing volatile"); -namespace llvm { +namespace { TEST(ArrayRefTest, AllocatorCopy) { BumpPtrAllocator Alloc; @@ -45,6 +45,18 @@ TEST(ArrayRefTest, AllocatorCopy) { EXPECT_NE(Array1.data(), Array1c.data()); EXPECT_TRUE(Array2.equals(Array2c)); EXPECT_NE(Array2.data(), Array2c.data()); + + // Check that copy can cope with uninitialized memory. + struct NonAssignable { + const char *Ptr; + + NonAssignable(const NonAssignable &RHS) = default; + void operator=(const NonAssignable &RHS) { assert(RHS.Ptr != nullptr); } + bool operator==(const NonAssignable &RHS) const { return Ptr == RHS.Ptr; } + } Array3Src[] = {{"hello"}, {"world"}}; + ArrayRef Array3Copy = makeArrayRef(Array3Src).copy(Alloc); + EXPECT_EQ(makeArrayRef(Array3Src), Array3Copy); + EXPECT_NE(makeArrayRef(Array3Src).data(), Array3Copy.data()); } TEST(ArrayRefTest, DropBack) { -- 2.7.4