diff --git a/libcxx/include/list b/libcxx/include/list index 32e9a27bd2a4ba81c698ac6d85aeb00da312880b..f884b168126f4724c8a3822b5f60101f4cfcd4eb 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -2058,15 +2058,15 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con #endif if (__f != __l) { + __link_pointer __first = __f.__ptr_; + --__l; + __link_pointer __last = __l.__ptr_; if (this != &__c) { - size_type __s = _VSTD::distance(__f, __l); + size_type __s = _VSTD::distance(__f, __l) + 1; __c.__sz() -= __s; base::__sz() += __s; } - __link_pointer __first = __f.__ptr_; - --__l; - __link_pointer __last = __l.__ptr_; base::__unlink_nodes(__first, __last); __link_nodes(__p.__ptr_, __first, __last); #if _LIBCPP_DEBUG_LEVEL >= 2 diff --git a/libcxx/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp b/libcxx/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp index 3ae009a8e96c75d768343d4b50809b7feb606efe..57d16c2723f75b875a17332ab4c5ddd9e83f7eec 100644 --- a/libcxx/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp +++ b/libcxx/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp @@ -42,6 +42,7 @@ public: Base::run(); try { FrontOnEmptyContainer(); + if constexpr (CT != CT_ForwardList) { AssignInvalidates(); BackOnEmptyContainer(); @@ -50,6 +51,8 @@ public: InsertIterIterIter(); EmplaceIterValue(); EraseIterIter(); + } else { + SpliceFirstElemAfter(); } if constexpr (CT == CT_Vector || CT == CT_Deque || CT == CT_List) { PopBack(); @@ -57,12 +60,66 @@ public: if constexpr (CT == CT_List || CT == CT_Deque) { PopFront(); // FIXME: Run with forward list as well } + if constexpr (CT == CT_List || CT == CT_ForwardList) { + RemoveFirstElem(); + } + if constexpr (CT == CT_List) { + SpliceFirstElem(); + } } catch (...) { assert(false && "uncaught debug exception"); } } private: + static void RemoveFirstElem() { + // See llvm.org/PR35564 + CHECKPOINT("remove(<first-elem>)"); + { + Container C = makeContainer(1); + auto FirstVal = *(C.begin()); + C.remove(FirstVal); + assert(C.empty()); + } + { + Container C = {1, 1, 1, 1}; + auto FirstVal = *(C.begin()); + C.remove(FirstVal); + assert(C.empty()); + } + } + + static void SpliceFirstElem() { + // See llvm.org/PR35564 + CHECKPOINT("splice(<first-elem>)"); + { + Container C = makeContainer(1); + Container C2; + C2.splice(C2.end(), C, C.begin(), ++C.begin()); + } + { + Container C = makeContainer(1); + Container C2; + C2.splice(C2.end(), C, C.begin()); + } + } + + + static void SpliceFirstElemAfter() { + // See llvm.org/PR35564 + CHECKPOINT("splice(<first-elem>)"); + { + Container C = makeContainer(1); + Container C2; + C2.splice_after(C2.begin(), C, C.begin(), ++C.begin()); + } + { + Container C = makeContainer(1); + Container C2; + C2.splice_after(C2.begin(), C, C.begin()); + } + } + static void AssignInvalidates() { CHECKPOINT("assign(Size, Value)"); Container C(allocator_type{});