[libcxx-commits] [libcxx] [libc++] Fix shrink_to_fit implementation for vector<bool> (PR #120495)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Dec 18 15:29:22 PST 2024
https://github.com/winner245 created https://github.com/llvm/llvm-project/pull/120495
The current implementation of `vector<bool>::shrink_to_fit` contains a logical error that prevents the function from doing anything, i.e., it will never shrink the capacity. This is because the current implementation checks the following condition
```cpp
if (__external_cap_to_internal(size()) > __cap_) {
do_shrink();
}
```
However, this condition is always false, as the number of used internal words `__external_cap_to_internal(size())` will never exceed the internal storage capacity (`__cap_`). This appears to be an implementation error, particularly since a similar logical error was found in the `reserve()` function of `__split_buffer` in #105681 and was corrected last month.
While the current implementation technically conforms to the standard—since the request to shrink is non-binding—it's hard to believe this implementation was intentional. If this were intentional, an empty function body would yield an equivalent effect, which raises doubts about the original intent of the implementation.
This PR addresses the issue by modifying `shrink_to_fit` to actually perform the necessary capacity reduction, ensuring it behaves as expected.
>From 89af9e271ad4fdb24521f37c551926fc4f602f51 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Wed, 18 Dec 2024 18:23:11 -0500
Subject: [PATCH] Fix shrink_to_fit for vector<bool>
---
libcxx/include/__vector/vector_bool.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 36eb7f350ac406..190ea2585b7821 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -841,11 +841,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
template <class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT {
- if (__external_cap_to_internal(size()) > __cap_) {
+ if (__external_cap_to_internal(size()) < __cap_) {
#if _LIBCPP_HAS_EXCEPTIONS
try {
#endif // _LIBCPP_HAS_EXCEPTIONS
- vector(*this, allocator_type(__alloc_)).swap(*this);
+ vector __v(*this, allocator_type(__alloc_));
+ if (__v.__cap_ < __cap_)
+ __v.swap(*this);
#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
}
More information about the libcxx-commits
mailing list