From df7c5d4137fd5cf63d9a9b0f09c9d7255895908c Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 27 Jul 2012 09:10:25 +0000 Subject: SmallVector::erase: Assert that iterators are actually inside the vector. The rationale here is that it's hard to write loops containing vector erases and it only shows up if the vector contains non-trivial objects leading to crashes when forming them out of garbage memory. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160854 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/SmallVector.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/llvm/ADT/SmallVector.h') diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index d124091..9ca0898 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -463,6 +463,7 @@ public: } iterator erase(iterator I) { + assert(I >= this->begin() && I < this->end() && "Iterator out of bounds"); iterator N = I; // Shift all elts down one. this->move(I+1, this->end(), I); @@ -472,6 +473,8 @@ public: } iterator erase(iterator S, iterator E) { + assert(S >= this->begin() && S <= E && E <= this->end() && + "Iterator range out of bounds"); iterator N = S; // Shift all elts down. iterator I = this->move(E, this->end(), S); -- cgit v1.1 From e82fafe9e22c7f0bb35ec4cb7d5428bf9e930807 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 27 Jul 2012 19:05:58 +0000 Subject: SmallVector: Crank up verbosity of asserts per Chandler's request. Also add assertions to validate the iterator in the insert method overloads. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160882 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/SmallVector.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'include/llvm/ADT/SmallVector.h') diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 9ca0898..2dbe708 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -463,7 +463,9 @@ public: } iterator erase(iterator I) { - assert(I >= this->begin() && I < this->end() && "Iterator out of bounds"); + assert(I >= this->begin() && "Iterator to erase is out of bounds."); + assert(I < this->end() && "Erasing at past-the-end iterator."); + iterator N = I; // Shift all elts down one. this->move(I+1, this->end(), I); @@ -473,8 +475,10 @@ public: } iterator erase(iterator S, iterator E) { - assert(S >= this->begin() && S <= E && E <= this->end() && - "Iterator range out of bounds"); + assert(S >= this->begin() && "Range to erase is out of bounds."); + assert(S <= E && "Trying to erase invalid range."); + assert(E <= this->end() && "Trying to erase past the end."); + iterator N = S; // Shift all elts down. iterator I = this->move(E, this->end(), S); @@ -491,6 +495,9 @@ public: return this->end()-1; } + assert(I >= this->begin() && "Insertion iterator is out of bounds."); + assert(I <= this->end() && "Inserting past the end of the vector."); + if (this->EndX < this->CapacityX) { Retry: ::new ((void*) this->end()) T(::std::move(this->back())); @@ -520,6 +527,9 @@ public: return this->end()-1; } + assert(I >= this->begin() && "Insertion iterator is out of bounds."); + assert(I <= this->end() && "Inserting past the end of the vector."); + if (this->EndX < this->CapacityX) { Retry: ::new ((void*) this->end()) T(this->back()); @@ -551,6 +561,9 @@ public: return this->begin()+InsertElt; } + assert(I >= this->begin() && "Insertion iterator is out of bounds."); + assert(I <= this->end() && "Inserting past the end of the vector."); + // Ensure there is enough space. reserve(static_cast(this->size() + NumToInsert)); @@ -599,6 +612,9 @@ public: return this->begin()+InsertElt; } + assert(I >= this->begin() && "Insertion iterator is out of bounds."); + assert(I <= this->end() && "Inserting past the end of the vector."); + size_t NumToInsert = std::distance(From, To); // Ensure there is enough space. -- cgit v1.1 From ba1f580f338e12c47a600050f7a77fae579acf93 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 30 Jul 2012 22:17:52 +0000 Subject: Move the SmallVector unit tests to be type-parameterized so that we can test more than a single instantiation of SmallVector. Add testing for 0, 1, 2, and 4 element sized "small" buffers. These appear to be essentially untested in the unit tests until now. Fix several tests to be robust in the face of a '0' small buffer. As a consequence of this size buffer, the growth patterns are actually observable in the test -- yes this means that many tests never caused a grow to occur before. For some tests I've merely added a reserve call to normalize behavior. For others, the growth is actually interesting, and so I captured the fact that growth would occur and adjusted the assertions to not assume how rapidly growth occured. Also update the specialization for a '0' small buffer length to have all the same interface points as the normal small vector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161001 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/SmallVector.h | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'include/llvm/ADT/SmallVector.h') diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 2dbe708..9fbbbe4 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -918,7 +918,8 @@ public: template class SmallVector : public SmallVectorImpl { public: - SmallVector() : SmallVectorImpl(0) {} + SmallVector() : SmallVectorImpl(0) { + } explicit SmallVector(unsigned Size, const T &Value = T()) : SmallVectorImpl(0) { @@ -931,13 +932,26 @@ public: } SmallVector(const SmallVector &RHS) : SmallVectorImpl(0) { + if (!RHS.empty()) + SmallVectorImpl::operator=(RHS); + } + + const SmallVector &operator=(const SmallVector &RHS) { SmallVectorImpl::operator=(RHS); + return *this; } - SmallVector &operator=(const SmallVectorImpl &RHS) { - return SmallVectorImpl::operator=(RHS); +#if LLVM_USE_RVALUE_REFERENCES + SmallVector(SmallVector &&RHS) : SmallVectorImpl(0) { + if (!RHS.empty()) + SmallVectorImpl::operator=(::std::move(RHS)); } + const SmallVector &operator=(SmallVector &&RHS) { + SmallVectorImpl::operator=(::std::move(RHS)); + return *this; + } +#endif }; template -- cgit v1.1