From 4979c8a20bfa00f002a30bdf8aa034d89bcdb1b9 Mon Sep 17 00:00:00 2001 From: Sergei Date: Mon, 14 Jul 2025 10:50:28 +0300 Subject: [PATCH] Fix bug in the `void etl::unlink(first, last)` for bidirectional links. (#1149) * Reproduce bug in the `void etl::unlink(first, last)` for bidirectional links. - correct `test_unlink_range_bidirectional_link` unit test according to the documentation - now this test fails. - enhance `test_intrusive_list::test_splice_range_self` unit test to verify also `etl_previous` links after splicing lists - now unit test crashes. * Fix bug in the `void etl::unlink(first, last)` for bidirectional links. - `test_unlink_range_bidirectional_link` unit test now is green. - `test_intrusive_list::test_splice_range_self` is not crashing anymore and green. --- include/etl/intrusive_links.h | 1 - test/test_intrusive_links.cpp | 7 +++---- test/test_intrusive_list.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/etl/intrusive_links.h b/include/etl/intrusive_links.h index 9f0e5514..5c9544bf 100644 --- a/include/etl/intrusive_links.h +++ b/include/etl/intrusive_links.h @@ -882,7 +882,6 @@ namespace etl if (first.etl_previous != ETL_NULLPTR) { first.etl_previous->etl_next = last.etl_next; - last.clear(); } first.etl_previous = ETL_NULLPTR; diff --git a/test/test_intrusive_links.cpp b/test/test_intrusive_links.cpp index cdfa1d8c..2b8d0445 100644 --- a/test/test_intrusive_links.cpp +++ b/test/test_intrusive_links.cpp @@ -1225,15 +1225,14 @@ namespace etl::link(data1, data0); etl::link(data0, nullptr); + // According to the documentation, `data1`/`data2` remain linked to each other. etl::unlink(data1, data2); - data1.BLink0::clear(); - data2.BLink0::clear(); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data3); CHECK(data1.BLink0::etl_previous == nullptr); - CHECK(data1.BLink0::etl_next == nullptr); - CHECK(data2.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_next == &data2); + CHECK(data2.BLink0::etl_previous == &data1); CHECK(data2.BLink0::etl_next == nullptr); CHECK(data3.BLink0::etl_previous == &data0); CHECK(data3.BLink0::etl_next == nullptr); diff --git a/test/test_intrusive_list.cpp b/test/test_intrusive_list.cpp index 45de6003..c997c610 100644 --- a/test/test_intrusive_list.cpp +++ b/test/test_intrusive_list.cpp @@ -1420,6 +1420,12 @@ namespace CHECK(are_equal); CHECK_EQUAL(data0.size(), compare0.size()); + + // Double check that after splicing `etl_previous` is also correct - `.reverse()` easy way to do so. + data0.reverse(); + compare0.reverse(); + are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); + CHECK(are_equal); } //*************************************************************************