Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2018-06-13 19:57:18 +0300
committerTom Stellard <tstellar@redhat.com>2018-06-13 19:57:18 +0300
commit7daf52428ce5d8ded1b992e551f22bb7eb1db851 (patch)
treeaf395ff25aa90facfdc5959347173db9cd8dd04a /libcxx/test
parent4f031296e9373790f82a7bdf9deed3d71c109000 (diff)
Merging r323390:
------------------------------------------------------------------------ r323390 | ericwf | 2018-01-24 16:02:48 -0800 (Wed, 24 Jan 2018) | 9 lines Fix PR35564 - std::list splice/erase incorrectly throw in debug mode. There was a bug in the implementation of splice where the container sizes were updated before decrementing one of the iterators. Afterwards, the result of decrementing the iterator was flagged as UB by the debug implementation because the container was reported to be empty. This patch fixes that bug by delaying the updating of the container sizes until after the iterators have been correctly constructed. ------------------------------------------------------------------------ llvm-svn: 334621
Diffstat (limited to 'libcxx/test')
-rw-r--r--libcxx/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp57
1 files changed, 57 insertions, 0 deletions
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 3ae009a8e96c..57d16c2723f7 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{});