diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 94bd9cc7b2c..075b13084aa 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -555,7 +555,8 @@ public: // reallocate the vector. if (size_t(this->end()-I) >= NumToInsert) { T *OldEnd = this->end(); - append(this->end()-NumToInsert, this->end()); + append(std::move_iterator(this->end() - NumToInsert), + std::move_iterator(this->end())); // Copy the existing elements that get replaced. this->move_backward(I, OldEnd-NumToInsert, OldEnd); diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index cceed7b92c4..079cc012b2e 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -26,8 +26,12 @@ namespace { class Constructable { private: static int numConstructorCalls; + static int numMoveConstructorCalls; + static int numCopyConstructorCalls; static int numDestructorCalls; static int numAssignmentCalls; + static int numMoveAssignmentCalls; + static int numCopyAssignmentCalls; bool constructed; int value; @@ -44,11 +48,13 @@ public: Constructable(const Constructable & src) : constructed(true) { value = src.value; ++numConstructorCalls; + ++numCopyConstructorCalls; } Constructable(Constructable && src) : constructed(true) { value = src.value; ++numConstructorCalls; + ++numMoveConstructorCalls; } ~Constructable() { @@ -61,6 +67,7 @@ public: EXPECT_TRUE(constructed); value = src.value; ++numAssignmentCalls; + ++numCopyAssignmentCalls; return *this; } @@ -68,6 +75,7 @@ public: EXPECT_TRUE(constructed); value = src.value; ++numAssignmentCalls; + ++numMoveAssignmentCalls; return *this; } @@ -77,18 +85,42 @@ public: static void reset() { numConstructorCalls = 0; + numMoveConstructorCalls = 0; + numCopyConstructorCalls = 0; numDestructorCalls = 0; numAssignmentCalls = 0; + numMoveAssignmentCalls = 0; + numCopyAssignmentCalls = 0; } static int getNumConstructorCalls() { return numConstructorCalls; } + static int getNumMoveConstructorCalls() { + return numMoveConstructorCalls; + } + + static int getNumCopyConstructorCalls() { + return numCopyConstructorCalls; + } + static int getNumDestructorCalls() { return numDestructorCalls; } + static int getNumAssignmentCalls() { + return numAssignmentCalls; + } + + static int getNumMoveAssignmentCalls() { + return numMoveAssignmentCalls; + } + + static int getNumCopyAssignmentCalls() { + return numCopyAssignmentCalls; + } + friend bool operator==(const Constructable & c0, const Constructable & c1) { return c0.getValue() == c1.getValue(); } @@ -100,8 +132,12 @@ public: }; int Constructable::numConstructorCalls; +int Constructable::numCopyConstructorCalls; +int Constructable::numMoveConstructorCalls; int Constructable::numDestructorCalls; int Constructable::numAssignmentCalls; +int Constructable::numCopyAssignmentCalls; +int Constructable::numMoveAssignmentCalls; // Test fixture class template @@ -430,8 +466,10 @@ TYPED_TEST(SmallVectorTest, InsertRepeatedTest) { SCOPED_TRACE("InsertRepeatedTest"); this->makeSequence(this->theVector, 10, 15); + Constructable::reset(); typename TypeParam::iterator I = this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16)); + EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls()); EXPECT_EQ(this->theVector.begin() + 1, I); this->assertValuesInOrder(this->theVector, 8u, 10, 16, 16, 11, 12, 13, 14, 15);