[libcxx-commits] [libcxx] [libc++][string] Replace ASAN volatile wrapper with memory barrier (PR #184693)
Vitaly Buka via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Mar 5 08:03:12 PST 2026
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/184693
>From 89d1b4f6fce2e369ae08d865bfa2318c046b4375 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 4 Mar 2026 14:33:25 -0800
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
libcxx/include/string | 49 +++++++++++++++++++------------------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index c4bf970e55004..8e0b0648da42d 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -770,30 +770,6 @@ public:
void>;
# endif
-# if _LIBCPP_ENABLE_ASAN_CONTAINER_CHECKS_FOR_STRING
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __asan_volatile_wrapper(pointer const& __ptr) const {
- if (__libcpp_is_constant_evaluated())
- return __ptr;
-
- pointer volatile __copy_ptr = __ptr;
-
- return const_cast<pointer&>(__copy_ptr);
- }
-
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer
- __asan_volatile_wrapper(const_pointer const& __ptr) const {
- if (__libcpp_is_constant_evaluated())
- return __ptr;
-
- const_pointer volatile __copy_ptr = __ptr;
-
- return const_cast<const_pointer&>(__copy_ptr);
- }
-# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) __asan_volatile_wrapper(PTR)
-# else
-# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) PTR
-# endif
-
static_assert(!is_array<value_type>::value, "Character type of basic_string must not be an array");
static_assert(is_standard_layout<value_type>::value, "Character type of basic_string must be standard-layout");
static_assert(is_trivially_default_constructible<value_type>::value,
@@ -2204,6 +2180,7 @@ private:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS size_type
__get_short_size() const _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(!__rep_.__s.__is_long_, "String has to be short when trying to get the short size");
+ __annotate_memory_barrier();
return __rep_.__s.__size_;
}
@@ -2213,6 +2190,7 @@ private:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_size() const _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long size");
+ __annotate_memory_barrier();
return __rep_.__l.__size_;
}
@@ -2225,27 +2203,32 @@ private:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long capacity");
+ __annotate_memory_barrier();
return __rep_.__l.__cap_ * __endian_factor;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_long_pointer() _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
- return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
+ __annotate_memory_barrier();
+ return __rep_.__l.__data_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_long_pointer() const _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
- return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
+ __annotate_memory_barrier();
+ return __rep_.__l.__data_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS pointer
__get_short_pointer() _NOEXCEPT {
- return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<pointer>::pointer_to(__rep_.__s.__data_[0]));
+ __annotate_memory_barrier();
+ return pointer_traits<pointer>::pointer_to(__rep_.__s.__data_[0]);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS const_pointer
__get_short_pointer() const _NOEXCEPT {
- return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<const_pointer>::pointer_to(__rep_.__s.__data_[0]));
+ __annotate_memory_barrier();
+ return pointer_traits<const_pointer>::pointer_to(__rep_.__s.__data_[0]);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_pointer() _NOEXCEPT {
@@ -2329,6 +2312,16 @@ private:
# endif
}
+ // Prevents speculative load before short/long state is determined.
+ // The following functions are no-ops outside of AddressSanitizer mode.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_memory_barrier() const {
+# if _LIBCPP_ENABLE_ASAN_CONTAINER_CHECKS_FOR_STRING
+ if (__libcpp_is_constant_evaluated())
+ return;
+ __asm__ volatile("" ::: "memory");
+# endif
+ }
+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_new(size_type __current_size) const _NOEXCEPT {
__annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1);
}
More information about the libcxx-commits
mailing list