[libcxx-commits] [libcxx] [libcxx][string] Replace ASAN volatile wrapper with memory barrier (PR #184693)

Vitaly Buka via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 4 15:01:00 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