aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-06-07 18:42:53 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-06-10 07:29:30 +0000
commitef4d145057c10e452ac07b3111b4b4d0c5382fb5 (patch)
treea71b15236a48e90ce66eede3e64bbf311c693fd4
parent960554869b2059f852155c9e15c16def9fab2f1c (diff)
downloadsrc-ef4d145057c10e452ac07b3111b4b4d0c5382fb5.tar.gz
src-ef4d145057c10e452ac07b3111b4b4d0c5382fb5.zip
Merge commit 382f70a877f0 from llvm-project (by Louis Dionne):
[libc++][NFC] Rewrite function call on two lines for clarity (#79141) Previously, there was a ternary conditional with a less-than comparison appearing inside a template argument, which was really confusing because of the <...> of the function template. This patch rewrites the same statement on two lines for clarity. Merge commit d129ea8d2fa3 from llvm-project (by Vitaly Buka): [libcxx] Align `__recommend() + 1` by __endian_factor (#90292) This is detected by asan after #83774 Allocation size will be divided by `__endian_factor` before storing. If it's not aligned, we will not be able to recover allocation size to pass into `__alloc_traits::deallocate`. we have code like this ``` auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); __p = __allocation.ptr; __set_long_cap(__allocation.count); void __set_long_cap(size_type __s) _NOEXCEPT { __r_.first().__l.__cap_ = __s / __endian_factor; __r_.first().__l.__is_long_ = true; } size_type __get_long_cap() const _NOEXCEPT { return __r_.first().__l.__cap_ * __endian_factor; } inline ~basic_string() { __annotate_delete(); if (__is_long()) __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); } ``` 1. __recommend() -> even size 2. `std::__allocate_at_least(__alloc(), __recommend(__sz) + 1)` - > not even size 3. ` __set_long_cap() `- > lose one bit of size for __endian_factor == 2 (see `/ __endian_factor`) 4. `__alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap())` -> uses even size (see `__get_long_cap`) This should fix incorrect deallocation sizes for some instances of std::string. Memory profiling or debugging tools like AddressSanitizer, LeakSanitizer or TCMalloc could then complain about the the size passed to a deallocation not matching the size originally passed to the allocation. Reported by: Aliaksei Kandratsenka <alkondratenko@gmail.com> PR: 279560 MFC after: 3 days (cherry picked from commit ead8e4c081e5c4de4d508fc353f381457b058ca6)
-rw-r--r--contrib/llvm-project/libcxx/include/string6
1 files changed, 3 insertions, 3 deletions
diff --git a/contrib/llvm-project/libcxx/include/string b/contrib/llvm-project/libcxx/include/string
index ba169c3dbfc9..56e2ef09947f 100644
--- a/contrib/llvm-project/libcxx/include/string
+++ b/contrib/llvm-project/libcxx/include/string
@@ -1943,10 +1943,10 @@ private:
if (__s < __min_cap) {
return static_cast<size_type>(__min_cap) - 1;
}
- size_type __guess =
- __align_it < sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : 1 > (__s + 1) - 1;
+ const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
+ size_type __guess = __align_it<__boundary>(__s + 1) - 1;
if (__guess == __min_cap)
- ++__guess;
+ __guess += __endian_factor;
return __guess;
}