https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/95264
Backport 382f70a877f0 d129ea8d2fa3 Requested by: @DimitryAndric >From bc2f4cbcc3e734c0ae847964f0c7f1912e770e16 Mon Sep 17 00:00:00 2001 From: Louis Dionne <ldionn...@gmail.com> Date: Wed, 24 Jan 2024 09:28:58 -0500 Subject: [PATCH 1/2] [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. (cherry picked from commit 382f70a877f00ab71f3cb5ba461b52e1b59cd292) --- libcxx/include/string | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/string b/libcxx/include/string index ba169c3dbfc9e..618ceb71b26b4 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1943,8 +1943,8 @@ 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) : 1; + size_type __guess = __align_it<__boundary>(__s + 1) - 1; if (__guess == __min_cap) ++__guess; return __guess; >From e803d6ad5a06fadd9755f4afe058acd69dd11089 Mon Sep 17 00:00:00 2001 From: Vitaly Buka <vitalyb...@google.com> Date: Thu, 2 May 2024 14:26:38 -0700 Subject: [PATCH 2/2] [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`) (cherry picked from commit d129ea8d2fa347e63deec0791faf389b84f20ce1) --- libcxx/include/string | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/string b/libcxx/include/string index 618ceb71b26b4..56e2ef09947f4 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1943,10 +1943,10 @@ private: if (__s < __min_cap) { return static_cast<size_type>(__min_cap) - 1; } - const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : 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; } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits