diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -721,21 +721,35 @@ void SmallVectorImpl::swap(SmallVectorImpl &RHS) { if (this == &RHS) return; - // We can only avoid copying elements if neither vector is small. - if (!this->isSmall() && !RHS.isSmall()) { + auto SwapBuffers = [&] { std::swap(this->BeginX, RHS.BeginX); std::swap(this->Size, RHS.Size); std::swap(this->Capacity, RHS.Capacity); + }; + + // We can only avoid copying elements if neither vector is small. + if (!this->isSmall() && !RHS.isSmall()) { + SwapBuffers(); return; } - if (RHS.size() > this->capacity()) + if (RHS.size() > this->capacity()) { this->grow(RHS.size()); - if (this->size() > RHS.capacity()) + if (!RHS.isSmall()) { + // Neither are small now, so swap the buffers. + SwapBuffers(); + return; + } + } else if (this->size() > RHS.capacity()) { RHS.grow(this->size()); + if (!this->isSmall()) { + // Neither are small now, so swap the buffers. + SwapBuffers(); + return; + } + } // Swap the shared elements. - size_t NumShared = this->size(); - if (NumShared > RHS.size()) NumShared = RHS.size(); + size_t NumShared = std::min(this->size(), RHS.size()); for (size_type i = 0; i != NumShared; ++i) std::swap((*this)[i], RHS[i]);