From 2a458005d99882e1e7487bcb7782dee3b1a1de72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 10 Nov 2020 10:08:03 +0100 Subject: [PATCH] Fixes #171 ("deque::clear() uses undefined behaviour") --- doc/container.qbk | 2 ++ include/boost/container/deque.hpp | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/doc/container.qbk b/doc/container.qbk index f654c3b..9baf77a 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1341,6 +1341,8 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes_boost_1_76_00 Boost 1.76 Release] * Added [[no-discard]] attribute in all containers to catch bugs related to unused return values. +* Fixed bugs/issues: + * [@https://github.com/boostorg/container/issues/171 GitHub #171: ['"deque::clear() uses undefined behaviour"]]. [endsect] diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index 9ebb2ea..e94ea7b 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -1843,22 +1843,25 @@ class deque : protected deque_base::type, //! Complexity: Linear to the number of elements in the deque. void clear() BOOST_NOEXCEPT_OR_NOTHROW { - for (index_pointer node = this->members_.m_start.m_node + 1; - node < this->members_.m_finish.m_node; - ++node) { - this->priv_destroy_range(*node, *node + get_block_size()); - this->priv_deallocate_node(*node); - } + if (this->members_.m_finish != this->members_.m_start) { + + for (index_pointer node = this->members_.m_start.m_node + 1; + node < this->members_.m_finish.m_node; + ++node) { + this->priv_destroy_range(*node, *node + get_block_size()); + this->priv_deallocate_node(*node); + } - if (this->members_.m_start.m_node != this->members_.m_finish.m_node) { - this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last); - this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur); - this->priv_deallocate_node(this->members_.m_finish.m_first); - } - else - this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur); + if (this->members_.m_start.m_node != this->members_.m_finish.m_node) { + this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last); + this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur); + this->priv_deallocate_node(this->members_.m_finish.m_first); + } + else + this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur); - this->members_.m_finish = this->members_.m_start; + this->members_.m_finish = this->members_.m_start; + } } //! Effects: Returns true if x and y are equal