[libcxx-commits] [libcxx] [ASan][libc++] Update string ASan annotations to Zero-overhead (PR #76165)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Dec 21 12:32:47 PST 2023


https://github.com/AdvenamTacet updated https://github.com/llvm/llvm-project/pull/76165

>From df31c7d747997ca269bfa01781a28f97af7b016d Mon Sep 17 00:00:00 2001
From: Advenam Tacet <advenam.tacet at trailofbits.com>
Date: Thu, 21 Dec 2023 16:39:09 +0100
Subject: [PATCH 1/4] [ASan][libc++] Update string ASan annotations to
 Zero-overhead

This commit introduces Zero-overhead string ASan annotations by wrapping every call to ASan helper functions inside a constexpr if statement. This ensures that ASan checks are only performed at runtime when the compiler determines that the string is potentially vulnerable to memory safety issues. This approach significantly reduces the overhead of ASan while maintaining its effectiveness in detecting memory safety bugs.

While the intended execution path should not incur any overhead due to compiler optimizations, a few local variables solely accessed by ASan helper functions are not currently removed and we rely on optimizing them away. A future commit may reduce number of these variables.
---
 libcxx/include/string | 186 +++++++++++++++++++++++-------------------
 1 file changed, 101 insertions(+), 85 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index fdffca5aed18be..fcfee0e6e2f9df 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -659,6 +659,13 @@ _LIBCPP_PUSH_MACROS
 #else
 #  define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
 #endif
+#ifndef _IF_ASAN
+#  ifndef _LIBCPP_HAS_NO_ASAN
+#    define _IF_ASAN() if _LIBCPP_CONSTEXPR (true)
+#  else
+#    define _IF_ASAN() if _LIBCPP_CONSTEXPR (false)
+#  endif
+#endif
 #define _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED false
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -858,7 +865,7 @@ private:
       __set_long_pointer(__allocation);
       __set_long_size(__size);
     }
-    __annotate_new(__size);
+    _IF_ASAN() __annotate_new(__size);
   }
 
   template <class _Iter, class _Sent>
@@ -880,7 +887,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
       _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
       : __r_(__value_init_tag(), __default_init_tag()) {
-    __annotate_new(0);
+    _IF_ASAN() __annotate_new(0);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
@@ -890,14 +897,14 @@ public:
       _NOEXCEPT
 #endif
       : __r_(__value_init_tag(), __a) {
-    __annotate_new(0);
+    _IF_ASAN() __annotate_new(0);
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str)
       : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
     if (!__str.__is_long()) {
       __r_.first() = __str.__r_.first();
-      __annotate_new(__get_short_size());
+      _IF_ASAN() __annotate_new(__get_short_size());
     } else
       __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
   }
@@ -907,7 +914,7 @@ public:
       : __r_(__default_init_tag(), __a) {
     if (!__str.__is_long()) {
       __r_.first() = __str.__r_.first();
-      __annotate_new(__get_short_size());
+      _IF_ASAN() __annotate_new(__get_short_size());
     } else
       __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
   }
@@ -919,13 +926,19 @@ public:
 #  else
       _NOEXCEPT
 #  endif
+#ifndef _LIBCPP_HAS_NO_ASAN
       // Turning off ASan instrumentation for variable initialization with _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
       // does not work consistently during initialization of __r_, so we instead unpoison __str's memory manually first.
       // __str's memory needs to be unpoisoned only in the case where it's a short string.
       : __r_(((__str.__is_long() ? 0 : (__str.__annotate_delete(), 0)), std::move(__str.__r_))) {
+      // ASan TODO: ^ This line results in stack frame growth and isn't correctly optimized by the compiler.
+      //              It should be refactored to improve performance.
+#else
+      : __r_(std::move(__str.__r_)) {
+#endif
     __str.__r_.first() = __rep();
-    __str.__annotate_new(0);
-    if (!__is_long())
+    _IF_ASAN() __str.__annotate_new(0);
+    _IF_ASAN() if (!__is_long())
       __annotate_new(size());
   }
 
@@ -936,12 +949,12 @@ public:
     else {
       if (__libcpp_is_constant_evaluated())
         __r_.first() = __rep();
-      if (!__str.__is_long())
+      _IF_ASAN() if (!__str.__is_long())
         __str.__annotate_delete();
       __r_.first()       = __str.__r_.first();
       __str.__r_.first() = __rep();
-      __str.__annotate_new(0);
-      if (!__is_long() && this != &__str)
+      _IF_ASAN() __str.__annotate_new(0);
+      _IF_ASAN() if (!__is_long() && this != &__str)
         __annotate_new(size());
     }
   }
@@ -1100,7 +1113,7 @@ public:
 #endif // _LIBCPP_CXX03_LANG
 
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
-    __annotate_delete();
+    _IF_ASAN() __annotate_delete();
     if (__is_long())
       __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
   }
@@ -1357,20 +1370,22 @@ public:
     // Pilfer the allocation from __str.
     _LIBCPP_ASSERT_INTERNAL(__alloc() == __str.__alloc(), "__move_assign called with wrong allocator");
     size_type __old_sz = __str.size();
-    if (!__str.__is_long())
+    _IF_ASAN() if (!__str.__is_long())
       __str.__annotate_delete();
     __r_.first()       = __str.__r_.first();
     __str.__r_.first() = __rep();
-    __str.__annotate_new(0);
+    _IF_ASAN() __str.__annotate_new(0);
 
     _Traits::move(data(), data() + __pos, __len);
     __set_size(__len);
     _Traits::assign(data()[__len], value_type());
 
-    if (!__is_long()) {
-      __annotate_new(__len);
-    } else if (__old_sz > __len) {
-      __annotate_shrink(__old_sz);
+    _IF_ASAN() {
+      if (!__is_long()) {
+        __annotate_new(__len);
+      } else if (__old_sz > __len) {
+        __annotate_shrink(__old_sz);
+      }
     }
   }
 #endif
@@ -1801,7 +1816,7 @@ private:
     size_type __cap = capacity();
     value_type* __p;
     if (__cap - __sz >= __n) {
-      __annotate_increase(__n);
+      _IF_ASAN() __annotate_increase(__n);
       __p                = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __ip;
       if (__n_move != 0)
@@ -2026,7 +2041,7 @@ private:
         __clear_and_shrink();
         __alloc() = __str.__alloc();
       } else {
-        __annotate_delete();
+        _IF_ASAN() __annotate_delete();
         allocator_type __a = __str.__alloc();
         auto __allocation  = std::__allocate_at_least(__a, __str.__get_long_cap());
         __begin_lifetime(__allocation.ptr, __allocation.count);
@@ -2036,7 +2051,7 @@ private:
         __set_long_pointer(__allocation.ptr);
         __set_long_cap(__allocation.count);
         __set_long_size(__str.size());
-        __annotate_new(__get_long_size());
+        _IF_ASAN() __annotate_new(__get_long_size());
       }
     }
   }
@@ -2076,13 +2091,13 @@ private:
   // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) {
     size_type __old_size = size();
-    if (__n > __old_size)
+    _IF_ASAN() if (__n > __old_size)
       __annotate_increase(__n - __old_size);
     pointer __p =
         __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer());
     traits_type::move(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
-    if (__old_size > __n)
+    _IF_ASAN() if (__old_size > __n)
       __annotate_shrink(__old_size);
     return *this;
   }
@@ -2090,11 +2105,11 @@ private:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   __null_terminate_at(value_type* __p, size_type __newsz) {
     size_type __old_size = size();
-    if (__newsz > __old_size)
+    _IF_ASAN() if (__newsz > __old_size)
       __annotate_increase(__newsz - __old_size);
     __set_size(__newsz);
     traits_type::assign(__p[__newsz], value_type());
-    if (__old_size > __newsz)
+    _IF_ASAN() if (__old_size > __newsz)
       __annotate_shrink(__old_size);
     return *this;
   }
@@ -2189,7 +2204,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
   }
   traits_type::copy(std::__to_address(__p), __s, __sz);
   traits_type::assign(__p[__sz], value_type());
-  __annotate_new(__sz);
+  _IF_ASAN() __annotate_new(__sz);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2213,7 +2228,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
   }
   traits_type::copy(std::__to_address(__p), __s, __sz);
   traits_type::assign(__p[__sz], value_type());
-  __annotate_new(__sz);
+  _IF_ASAN() __annotate_new(__sz);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2237,7 +2252,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value
     __set_long_size(__sz);
   }
   traits_type::copy(std::__to_address(__p), __s, __sz + 1);
-  __annotate_new(__sz);
+  _IF_ASAN() __annotate_new(__sz);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2261,7 +2276,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   }
   traits_type::assign(std::__to_address(__p), __n, __c);
   traits_type::assign(__p[__n], value_type());
-  __annotate_new(__n);
+  _IF_ASAN() __annotate_new(__n);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2276,7 +2291,7 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
   __r_.first() = __rep();
-  __annotate_new(0);
+  _IF_ASAN() __annotate_new(0);
 
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
@@ -2285,7 +2300,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator _
       push_back(*__first);
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
-    __annotate_delete();
+    _IF_ASAN() __annotate_delete();
     if (__is_long())
       __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
     throw;
@@ -2338,7 +2353,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __fir
     throw;
   }
 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
-  __annotate_new(__sz);
+  _IF_ASAN() __annotate_new(__sz);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2356,7 +2371,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
-  __annotate_delete();
+  _IF_ASAN() __annotate_delete();
   auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
   pointer __p       = __allocation.ptr;
   __begin_lifetime(__p, __allocation.count);
@@ -2375,7 +2390,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   __old_sz = __n_copy + __n_add + __sec_cp_sz;
   __set_long_size(__old_sz);
   traits_type::assign(__p[__old_sz], value_type());
-  __annotate_new(__old_cap + __delta_cap);
+  _IF_ASAN() __annotate_new(__old_cap + __delta_cap);
 }
 
 // __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
@@ -2399,7 +2414,7 @@ void _LIBCPP_CONSTEXPR_SINCE_CXX20
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
-  __annotate_delete();
+  _IF_ASAN() __annotate_delete();
   auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
   pointer __p       = __allocation.ptr;
   __begin_lifetime(__p, __allocation.count);
@@ -2428,7 +2443,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
   __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
   _LIBCPP_SUPPRESS_DEPRECATED_POP
   __set_long_size(__old_sz - __n_del + __n_add);
-  __annotate_new(__old_sz - __n_del + __n_add);
+  _IF_ASAN() __annotate_new(__old_sz - __n_del + __n_add);
 }
 
 // assign
@@ -2440,13 +2455,13 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* _
   size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
   if (__n < __cap) {
     size_type __old_size = __is_short ? __get_short_size() : __get_long_size();
-    if (__n > __old_size)
+    _IF_ASAN() if (__n > __old_size)
       __annotate_increase(__n - __old_size);
     pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
     __is_short ? __set_short_size(__n) : __set_long_size(__n);
     traits_type::copy(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
-    if (__old_size > __n)
+    _IF_ASAN() if (__old_size > __n)
       __annotate_shrink(__old_size);
   } else {
     size_type __sz = __is_short ? __get_short_size() : __get_long_size();
@@ -2461,7 +2476,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* _
   size_type __cap = capacity();
   if (__cap >= __n) {
     size_type __old_size = size();
-    if (__n > __old_size)
+    _IF_ASAN() if (__n > __old_size)
       __annotate_increase(__n - __old_size);
     value_type* __p = std::__to_address(__get_pointer());
     traits_type::move(__p, __s, __n);
@@ -2488,8 +2503,8 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
   if (__cap < __n) {
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
-    __annotate_increase(__n);
-  } else if (__n > __old_size)
+    _IF_ASAN() __annotate_increase(__n);
+  } else _IF_ASAN() if (__n > __old_size)
     __annotate_increase(__n - __old_size);
   value_type* __p = std::__to_address(__get_pointer());
   traits_type::assign(__p, __n, __c);
@@ -2501,7 +2516,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   pointer __p;
   size_type __old_size = size();
-  if (__old_size == 0)
+  _IF_ASAN() if (__old_size == 0)
     __annotate_increase(1);
   if (__is_long()) {
     __p = __get_long_pointer();
@@ -2512,7 +2527,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   }
   traits_type::assign(*__p, __c);
   traits_type::assign(*++__p, value_type());
-  if (__old_size > 1)
+  _IF_ASAN() if (__old_size > 1)
     __annotate_shrink(__old_size);
   return *this;
 }
@@ -2525,10 +2540,10 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
     if (!__is_long()) {
       if (!__str.__is_long()) {
         size_type __old_size = __get_short_size();
-        if (__get_short_size() < __str.__get_short_size())
+        _IF_ASAN() if (__get_short_size() < __str.__get_short_size())
           __annotate_increase(__str.__get_short_size() - __get_short_size());
         __r_.first() = __str.__r_.first();
-        if (__old_size > __get_short_size())
+        _IF_ASAN() if (__old_size > __get_short_size())
           __annotate_shrink(__old_size);
       } else {
         return __assign_no_alias<true>(__str.data(), __str.size());
@@ -2561,14 +2576,14 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
 #  endif
 {
-  __annotate_delete();
+  _IF_ASAN() __annotate_delete();
   if (__is_long()) {
     __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
 #  if _LIBCPP_STD_VER <= 14
     if (!is_nothrow_move_assignable<allocator_type>::value) {
       __set_short_size(0);
       traits_type::assign(__get_short_pointer()[0], value_type());
-      __annotate_new(0);
+      _IF_ASAN() __annotate_new(0);
     }
 #  endif
   }
@@ -2579,24 +2594,25 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
   __r_.first() = __str.__r_.first();
   __str.__set_short_size(0);
   traits_type::assign(__str.__get_short_pointer()[0], value_type());
+  _IF_ASAN() {
+    if (__str_was_short && this != &__str)
+      __str.__annotate_shrink(__str_old_size);
+    else
+      // ASan annotations: was long, so object memory is unpoisoned as new.
+      // Or is same as *this, and __annotate_delete() was called.
+      __str.__annotate_new(0);
 
-  if (__str_was_short && this != &__str)
-    __str.__annotate_shrink(__str_old_size);
-  else
-    // ASan annotations: was long, so object memory is unpoisoned as new.
-    // Or is same as *this, and __annotate_delete() was called.
-    __str.__annotate_new(0);
-
-  // ASan annotations: Guard against `std::string s; s = std::move(s);`
-  // You can find more here: https://en.cppreference.com/w/cpp/utility/move
-  // Quote: "Unless otherwise specified, all standard library objects that have been moved
-  // from are placed in a "valid but unspecified state", meaning the object's class
-  // invariants hold (so functions without preconditions, such as the assignment operator,
-  // can be safely used on the object after it was moved from):"
-  // Quote: "v = std::move(v); // the value of v is unspecified"
-  if (!__is_long() && &__str != this)
-    // If it is long string, delete was never called on original __str's buffer.
-    __annotate_new(__get_short_size());
+    // ASan annotations: Guard against `std::string s; s = std::move(s);`
+    // You can find more here: https://en.cppreference.com/w/cpp/utility/move
+    // Quote: "Unless otherwise specified, all standard library objects that have been moved
+    // from are placed in a "valid but unspecified state", meaning the object's class
+    // invariants hold (so functions without preconditions, such as the assignment operator,
+    // can be safely used on the object after it was moved from):"
+    // Quote: "v = std::move(v); // the value of v is unspecified"
+    if (!__is_long() && &__str != this)
+      // If it is long string, delete was never called on original __str's buffer.
+      __annotate_new(__get_short_size());
+  }
 }
 
 #endif
@@ -2649,15 +2665,15 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _
     //    object itself stays valid even if reallocation happens.
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
-    __annotate_increase(__n);
-  } else if (__n > __old_size)
+    _IF_ASAN() __annotate_increase(__n);
+  } else _IF_ASAN() if (__n > __old_size)
     __annotate_increase(__n - __old_size);
   pointer __p = __get_pointer();
   for (; __first != __last; ++__p, (void)++__first)
     traits_type::assign(*__p, *__first);
   traits_type::assign(*__p, value_type());
   __set_size(__n);
-  if (__n < __old_size)
+  _IF_ASAN() if (__n < __old_size)
     __annotate_shrink(__old_size);
 }
 
@@ -2709,7 +2725,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
   size_type __sz  = size();
   if (__cap - __sz >= __n) {
     if (__n) {
-      __annotate_increase(__n);
+      _IF_ASAN() __annotate_increase(__n);
       value_type* __p = std::__to_address(__get_pointer());
       traits_type::copy(__p + __sz, __s, __n);
       __sz += __n;
@@ -2729,7 +2745,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
     size_type __sz  = size();
     if (__cap - __sz < __n)
       __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-    __annotate_increase(__n);
+    _IF_ASAN() __annotate_increase(__n);
     pointer __p = __get_pointer();
     traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
     __sz += __n;
@@ -2747,7 +2763,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
     size_type __sz  = size();
     if (__cap - __sz < __n)
       __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-    __annotate_increase(__n);
+    _IF_ASAN() __annotate_increase(__n);
     pointer __p = __get_pointer();
     __sz += __n;
     __set_size(__sz);
@@ -2769,10 +2785,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pu
   }
   if (__sz == __cap) {
     __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
-    __annotate_increase(1);
+    _IF_ASAN() __annotate_increase(1);
     __is_short = false; // the string is always long after __grow_by
   } else
-    __annotate_increase(1);
+    _IF_ASAN() __annotate_increase(1);
   pointer __p = __get_pointer();
   if (__is_short) {
     __p = __get_short_pointer() + __sz;
@@ -2796,7 +2812,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For
     if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
       if (__cap - __sz < __n)
         __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-      __annotate_increase(__n);
+      _IF_ASAN() __annotate_increase(__n);
       pointer __p = __get_pointer() + __sz;
       for (; __first != __last; ++__p, (void)++__first)
         traits_type::assign(*__p, *__first);
@@ -2852,7 +2868,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
   size_type __cap = capacity();
   if (__cap - __sz >= __n) {
     if (__n) {
-      __annotate_increase(__n);
+      _IF_ASAN() __annotate_increase(__n);
       value_type* __p    = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __pos;
       if (__n_move != 0) {
@@ -2880,7 +2896,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
     size_type __cap = capacity();
     value_type* __p;
     if (__cap - __sz >= __n) {
-      __annotate_increase(__n);
+      _IF_ASAN() __annotate_increase(__n);
       __p                = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __pos;
       if (__n_move != 0)
@@ -2973,7 +2989,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
     __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
     __p = std::__to_address(__get_long_pointer());
   } else {
-    __annotate_increase(1);
+    _IF_ASAN() __annotate_increase(1);
     __p                = std::__to_address(__get_pointer());
     size_type __n_move = __sz - __ip;
     if (__n_move != 0)
@@ -3001,7 +3017,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
   if (__cap - __sz + __n1 >= __n2) {
     value_type* __p = std::__to_address(__get_pointer());
     if (__n1 != __n2) {
-      if (__n2 > __n1)
+      _IF_ASAN() if (__n2 > __n1)
         __annotate_increase(__n2 - __n1);
       size_type __n_move = __sz - __pos - __n1;
       if (__n_move != 0) {
@@ -3044,7 +3060,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
   if (__cap - __sz + __n1 >= __n2) {
     __p = std::__to_address(__get_pointer());
     if (__n1 != __n2) {
-      if (__n2 > __n1)
+      _IF_ASAN() if (__n2 > __n1)
         __annotate_increase(__n2 - __n1);
       size_type __n_move = __sz - __pos - __n1;
       if (__n_move != 0)
@@ -3167,7 +3183,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
     traits_type::assign(*__get_short_pointer(), value_type());
     __set_short_size(0);
   }
-  __annotate_shrink(__old_size);
+  _IF_ASAN() __annotate_shrink(__old_size);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3220,7 +3236,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) {
-  __annotate_delete();
+  _IF_ASAN() __annotate_delete();
   size_type __cap = capacity();
   size_type __sz  = size();
 
@@ -3266,7 +3282,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
     __set_long_pointer(__new_data);
   } else
     __set_short_size(__sz);
-  __annotate_new(__sz);
+  _IF_ASAN() __annotate_new(__sz);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3308,15 +3324,15 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
       __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value ||
           __alloc() == __str.__alloc(),
       "swapping non-equal allocators");
-  if (!__is_long())
+  _IF_ASAN() if (!__is_long())
     __annotate_delete();
-  if (this != &__str && !__str.__is_long())
+  _IF_ASAN() if (this != &__str && !__str.__is_long())
     __str.__annotate_delete();
   std::swap(__r_.first(), __str.__r_.first());
   std::__swap_allocator(__alloc(), __str.__alloc());
-  if (!__is_long())
+  _IF_ASAN() if (!__is_long())
     __annotate_new(__get_short_size());
-  if (this != &__str && !__str.__is_long())
+  _IF_ASAN() if (this != &__str && !__str.__is_long())
     __str.__annotate_new(__str.__get_short_size());
 }
 
@@ -3673,7 +3689,7 @@ template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT {
   clear();
   if (__is_long()) {
-    __annotate_delete();
+    _IF_ASAN() __annotate_delete();
     __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
     __r_.first() = __rep();
   }

>From 20601991670b9d92f602db38bdbad60547800cab Mon Sep 17 00:00:00 2001
From: Advenam Tacet <advenam.tacet at trailofbits.com>
Date: Thu, 21 Dec 2023 18:32:54 +0100
Subject: [PATCH 2/4] Fixes based on the code review

(1) Renamed to `_LIBCPP_IF_ASAN`.
(2) Moved to `__config`.
(3) Added `{ ... }` after `_LIBCPP_IF_ASAN()`.

Missing: `#ifdef` around ASan related variables.
---
 libcxx/include/__config |  10 ++
 libcxx/include/string   | 231 +++++++++++++++++++++++-----------------
 2 files changed, 144 insertions(+), 97 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index adff13e714cb64..1e09851d404353 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1490,6 +1490,16 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
 #    define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
 #  endif
 
+// ASan related macros
+// _LIBCPP_IF_ASAN is used to removed ASan related code, whenever compiled without ASan.
+#ifndef _LIBCPP_IF_ASAN
+#  ifndef _LIBCPP_HAS_NO_ASAN
+#    define _LIBCPP_IF_ASAN() if _LIBCPP_CONSTEXPR (true)
+#  else
+#    define _LIBCPP_IF_ASAN() if _LIBCPP_CONSTEXPR (false)
+#  endif
+#endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/string b/libcxx/include/string
index fcfee0e6e2f9df..a32186e5abd80f 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -659,13 +659,6 @@ _LIBCPP_PUSH_MACROS
 #else
 #  define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
 #endif
-#ifndef _IF_ASAN
-#  ifndef _LIBCPP_HAS_NO_ASAN
-#    define _IF_ASAN() if _LIBCPP_CONSTEXPR (true)
-#  else
-#    define _IF_ASAN() if _LIBCPP_CONSTEXPR (false)
-#  endif
-#endif
 #define _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED false
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -865,7 +858,7 @@ private:
       __set_long_pointer(__allocation);
       __set_long_size(__size);
     }
-    _IF_ASAN() __annotate_new(__size);
+    _LIBCPP_IF_ASAN() { __annotate_new(__size); }
   }
 
   template <class _Iter, class _Sent>
@@ -887,7 +880,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
       _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
       : __r_(__value_init_tag(), __default_init_tag()) {
-    _IF_ASAN() __annotate_new(0);
+    _LIBCPP_IF_ASAN() { __annotate_new(0); }
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
@@ -897,14 +890,14 @@ public:
       _NOEXCEPT
 #endif
       : __r_(__value_init_tag(), __a) {
-    _IF_ASAN() __annotate_new(0);
+    _LIBCPP_IF_ASAN() { __annotate_new(0); }
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str)
       : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
     if (!__str.__is_long()) {
       __r_.first() = __str.__r_.first();
-      _IF_ASAN() __annotate_new(__get_short_size());
+      _LIBCPP_IF_ASAN() { __annotate_new(__get_short_size()); }
     } else
       __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
   }
@@ -914,7 +907,7 @@ public:
       : __r_(__default_init_tag(), __a) {
     if (!__str.__is_long()) {
       __r_.first() = __str.__r_.first();
-      _IF_ASAN() __annotate_new(__get_short_size());
+      _LIBCPP_IF_ASAN() { __annotate_new(__get_short_size()); }
     } else
       __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
   }
@@ -937,9 +930,11 @@ public:
       : __r_(std::move(__str.__r_)) {
 #endif
     __str.__r_.first() = __rep();
-    _IF_ASAN() __str.__annotate_new(0);
-    _IF_ASAN() if (!__is_long())
-      __annotate_new(size());
+    _LIBCPP_IF_ASAN() {
+      __str.__annotate_new(0);
+      if (!__is_long())
+        __annotate_new(size());
+    }
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a)
@@ -949,13 +944,17 @@ public:
     else {
       if (__libcpp_is_constant_evaluated())
         __r_.first() = __rep();
-      _IF_ASAN() if (!__str.__is_long())
-        __str.__annotate_delete();
+      _LIBCPP_IF_ASAN() {
+        if (!__str.__is_long())
+          __str.__annotate_delete();
+      }
       __r_.first()       = __str.__r_.first();
       __str.__r_.first() = __rep();
-      _IF_ASAN() __str.__annotate_new(0);
-      _IF_ASAN() if (!__is_long() && this != &__str)
-        __annotate_new(size());
+      _LIBCPP_IF_ASAN() {
+        __str.__annotate_new(0);
+        if (!__is_long() && this != &__str)
+          __annotate_new(size());
+      }
     }
   }
 #endif // _LIBCPP_CXX03_LANG
@@ -1113,7 +1112,7 @@ public:
 #endif // _LIBCPP_CXX03_LANG
 
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
-    _IF_ASAN() __annotate_delete();
+    _LIBCPP_IF_ASAN() { __annotate_delete(); }
     if (__is_long())
       __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
   }
@@ -1370,17 +1369,19 @@ public:
     // Pilfer the allocation from __str.
     _LIBCPP_ASSERT_INTERNAL(__alloc() == __str.__alloc(), "__move_assign called with wrong allocator");
     size_type __old_sz = __str.size();
-    _IF_ASAN() if (!__str.__is_long())
-      __str.__annotate_delete();
+    _LIBCPP_IF_ASAN() {
+      if (!__str.__is_long())
+        __str.__annotate_delete();
+    }
     __r_.first()       = __str.__r_.first();
     __str.__r_.first() = __rep();
-    _IF_ASAN() __str.__annotate_new(0);
+    _LIBCPP_IF_ASAN() { __str.__annotate_new(0); }
 
     _Traits::move(data(), data() + __pos, __len);
     __set_size(__len);
     _Traits::assign(data()[__len], value_type());
 
-    _IF_ASAN() {
+    _LIBCPP_IF_ASAN() {
       if (!__is_long()) {
         __annotate_new(__len);
       } else if (__old_sz > __len) {
@@ -1816,7 +1817,7 @@ private:
     size_type __cap = capacity();
     value_type* __p;
     if (__cap - __sz >= __n) {
-      _IF_ASAN() __annotate_increase(__n);
+      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
       __p                = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __ip;
       if (__n_move != 0)
@@ -2041,7 +2042,7 @@ private:
         __clear_and_shrink();
         __alloc() = __str.__alloc();
       } else {
-        _IF_ASAN() __annotate_delete();
+        _LIBCPP_IF_ASAN() { __annotate_delete(); }
         allocator_type __a = __str.__alloc();
         auto __allocation  = std::__allocate_at_least(__a, __str.__get_long_cap());
         __begin_lifetime(__allocation.ptr, __allocation.count);
@@ -2051,7 +2052,7 @@ private:
         __set_long_pointer(__allocation.ptr);
         __set_long_cap(__allocation.count);
         __set_long_size(__str.size());
-        _IF_ASAN() __annotate_new(__get_long_size());
+        _LIBCPP_IF_ASAN() { __annotate_new(__get_long_size()); }
       }
     }
   }
@@ -2091,26 +2092,34 @@ private:
   // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) {
     size_type __old_size = size();
-    _IF_ASAN() if (__n > __old_size)
-      __annotate_increase(__n - __old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__n > __old_size)
+        __annotate_increase(__n - __old_size);
+    }
     pointer __p =
         __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer());
     traits_type::move(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
-    _IF_ASAN() if (__old_size > __n)
-      __annotate_shrink(__old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__old_size > __n)
+        __annotate_shrink(__old_size);
+    }
     return *this;
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   __null_terminate_at(value_type* __p, size_type __newsz) {
     size_type __old_size = size();
-    _IF_ASAN() if (__newsz > __old_size)
-      __annotate_increase(__newsz - __old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__newsz > __old_size)
+        __annotate_increase(__newsz - __old_size);
+    }
     __set_size(__newsz);
     traits_type::assign(__p[__newsz], value_type());
-    _IF_ASAN() if (__old_size > __newsz)
-      __annotate_shrink(__old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__old_size > __newsz)
+        __annotate_shrink(__old_size);
+    }
     return *this;
   }
 
@@ -2204,7 +2213,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
   }
   traits_type::copy(std::__to_address(__p), __s, __sz);
   traits_type::assign(__p[__sz], value_type());
-  _IF_ASAN() __annotate_new(__sz);
+  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2228,7 +2237,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
   }
   traits_type::copy(std::__to_address(__p), __s, __sz);
   traits_type::assign(__p[__sz], value_type());
-  _IF_ASAN() __annotate_new(__sz);
+  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2252,7 +2261,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value
     __set_long_size(__sz);
   }
   traits_type::copy(std::__to_address(__p), __s, __sz + 1);
-  _IF_ASAN() __annotate_new(__sz);
+  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2276,7 +2285,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   }
   traits_type::assign(std::__to_address(__p), __n, __c);
   traits_type::assign(__p[__n], value_type());
-  _IF_ASAN() __annotate_new(__n);
+  _LIBCPP_IF_ASAN() { __annotate_new(__n); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2291,7 +2300,7 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
   __r_.first() = __rep();
-  _IF_ASAN() __annotate_new(0);
+  _LIBCPP_IF_ASAN() { __annotate_new(0); }
 
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
@@ -2300,7 +2309,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator _
       push_back(*__first);
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
-    _IF_ASAN() __annotate_delete();
+    _LIBCPP_IF_ASAN() { __annotate_delete(); }
     if (__is_long())
       __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
     throw;
@@ -2353,7 +2362,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __fir
     throw;
   }
 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
-  _IF_ASAN() __annotate_new(__sz);
+  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2371,7 +2380,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
-  _IF_ASAN() __annotate_delete();
+  _LIBCPP_IF_ASAN() { __annotate_delete(); }
   auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
   pointer __p       = __allocation.ptr;
   __begin_lifetime(__p, __allocation.count);
@@ -2390,7 +2399,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   __old_sz = __n_copy + __n_add + __sec_cp_sz;
   __set_long_size(__old_sz);
   traits_type::assign(__p[__old_sz], value_type());
-  _IF_ASAN() __annotate_new(__old_cap + __delta_cap);
+  _LIBCPP_IF_ASAN() { __annotate_new(__old_cap + __delta_cap); }
 }
 
 // __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
@@ -2414,7 +2423,7 @@ void _LIBCPP_CONSTEXPR_SINCE_CXX20
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
-  _IF_ASAN() __annotate_delete();
+  _LIBCPP_IF_ASAN() { __annotate_delete(); }
   auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
   pointer __p       = __allocation.ptr;
   __begin_lifetime(__p, __allocation.count);
@@ -2443,7 +2452,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
   __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
   _LIBCPP_SUPPRESS_DEPRECATED_POP
   __set_long_size(__old_sz - __n_del + __n_add);
-  _IF_ASAN() __annotate_new(__old_sz - __n_del + __n_add);
+  _LIBCPP_IF_ASAN() { __annotate_new(__old_sz - __n_del + __n_add); }
 }
 
 // assign
@@ -2455,14 +2464,18 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* _
   size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
   if (__n < __cap) {
     size_type __old_size = __is_short ? __get_short_size() : __get_long_size();
-    _IF_ASAN() if (__n > __old_size)
-      __annotate_increase(__n - __old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__n > __old_size)
+        __annotate_increase(__n - __old_size);
+    }
     pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
     __is_short ? __set_short_size(__n) : __set_long_size(__n);
     traits_type::copy(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
-    _IF_ASAN() if (__old_size > __n)
-      __annotate_shrink(__old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__old_size > __n)
+        __annotate_shrink(__old_size);
+    }
   } else {
     size_type __sz = __is_short ? __get_short_size() : __get_long_size();
     __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
@@ -2476,8 +2489,10 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* _
   size_type __cap = capacity();
   if (__cap >= __n) {
     size_type __old_size = size();
-    _IF_ASAN() if (__n > __old_size)
-      __annotate_increase(__n - __old_size);
+    _LIBCPP_IF_ASAN() {
+      if (__n > __old_size)
+        __annotate_increase(__n - __old_size);
+    }
     value_type* __p = std::__to_address(__get_pointer());
     traits_type::move(__p, __s, __n);
     return __null_terminate_at(__p, __n);
@@ -2503,9 +2518,11 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
   if (__cap < __n) {
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
-    _IF_ASAN() __annotate_increase(__n);
-  } else _IF_ASAN() if (__n > __old_size)
-    __annotate_increase(__n - __old_size);
+    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+  } else _LIBCPP_IF_ASAN() {
+      if (__n > __old_size)
+        __annotate_increase(__n - __old_size);
+    }
   value_type* __p = std::__to_address(__get_pointer());
   traits_type::assign(__p, __n, __c);
   return __null_terminate_at(__p, __n);
@@ -2516,8 +2533,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   pointer __p;
   size_type __old_size = size();
-  _IF_ASAN() if (__old_size == 0)
-    __annotate_increase(1);
+  _LIBCPP_IF_ASAN() {
+    if (__old_size == 0)
+      __annotate_increase(1);
+  }
   if (__is_long()) {
     __p = __get_long_pointer();
     __set_long_size(1);
@@ -2527,8 +2546,10 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   }
   traits_type::assign(*__p, __c);
   traits_type::assign(*++__p, value_type());
-  _IF_ASAN() if (__old_size > 1)
-    __annotate_shrink(__old_size);
+  _LIBCPP_IF_ASAN() {
+    if (__old_size > 1)
+      __annotate_shrink(__old_size);
+  }
   return *this;
 }
 
@@ -2540,11 +2561,15 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
     if (!__is_long()) {
       if (!__str.__is_long()) {
         size_type __old_size = __get_short_size();
-        _IF_ASAN() if (__get_short_size() < __str.__get_short_size())
-          __annotate_increase(__str.__get_short_size() - __get_short_size());
+        _LIBCPP_IF_ASAN() {
+          if (__get_short_size() < __str.__get_short_size())
+            __annotate_increase(__str.__get_short_size() - __get_short_size());
+        }
         __r_.first() = __str.__r_.first();
-        _IF_ASAN() if (__old_size > __get_short_size())
-          __annotate_shrink(__old_size);
+        _LIBCPP_IF_ASAN() {
+          if (__old_size > __get_short_size())
+            __annotate_shrink(__old_size);
+        }
       } else {
         return __assign_no_alias<true>(__str.data(), __str.size());
       }
@@ -2576,14 +2601,14 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
 #  endif
 {
-  _IF_ASAN() __annotate_delete();
+  _LIBCPP_IF_ASAN() { __annotate_delete(); }
   if (__is_long()) {
     __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
 #  if _LIBCPP_STD_VER <= 14
     if (!is_nothrow_move_assignable<allocator_type>::value) {
       __set_short_size(0);
       traits_type::assign(__get_short_pointer()[0], value_type());
-      _IF_ASAN() __annotate_new(0);
+      _LIBCPP_IF_ASAN() { __annotate_new(0); }
     }
 #  endif
   }
@@ -2594,7 +2619,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
   __r_.first() = __str.__r_.first();
   __str.__set_short_size(0);
   traits_type::assign(__str.__get_short_pointer()[0], value_type());
-  _IF_ASAN() {
+  _LIBCPP_IF_ASAN() {
     if (__str_was_short && this != &__str)
       __str.__annotate_shrink(__str_old_size);
     else
@@ -2665,16 +2690,20 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _
     //    object itself stays valid even if reallocation happens.
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
-    _IF_ASAN() __annotate_increase(__n);
-  } else _IF_ASAN() if (__n > __old_size)
-    __annotate_increase(__n - __old_size);
+    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+  } else _LIBCPP_IF_ASAN() {
+    if (__n > __old_size)
+      __annotate_increase(__n - __old_size);
+  }
   pointer __p = __get_pointer();
   for (; __first != __last; ++__p, (void)++__first)
     traits_type::assign(*__p, *__first);
   traits_type::assign(*__p, value_type());
   __set_size(__n);
-  _IF_ASAN() if (__n < __old_size)
-    __annotate_shrink(__old_size);
+  _LIBCPP_IF_ASAN() {
+    if (__n < __old_size)
+      __annotate_shrink(__old_size);
+  }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2725,7 +2754,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
   size_type __sz  = size();
   if (__cap - __sz >= __n) {
     if (__n) {
-      _IF_ASAN() __annotate_increase(__n);
+      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
       value_type* __p = std::__to_address(__get_pointer());
       traits_type::copy(__p + __sz, __s, __n);
       __sz += __n;
@@ -2745,7 +2774,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
     size_type __sz  = size();
     if (__cap - __sz < __n)
       __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-    _IF_ASAN() __annotate_increase(__n);
+    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
     pointer __p = __get_pointer();
     traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
     __sz += __n;
@@ -2763,7 +2792,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
     size_type __sz  = size();
     if (__cap - __sz < __n)
       __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-    _IF_ASAN() __annotate_increase(__n);
+    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
     pointer __p = __get_pointer();
     __sz += __n;
     __set_size(__sz);
@@ -2785,10 +2814,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pu
   }
   if (__sz == __cap) {
     __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
-    _IF_ASAN() __annotate_increase(1);
+    _LIBCPP_IF_ASAN() { __annotate_increase(1); }
     __is_short = false; // the string is always long after __grow_by
   } else
-    _IF_ASAN() __annotate_increase(1);
+    _LIBCPP_IF_ASAN() { __annotate_increase(1); }
   pointer __p = __get_pointer();
   if (__is_short) {
     __p = __get_short_pointer() + __sz;
@@ -2812,7 +2841,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For
     if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
       if (__cap - __sz < __n)
         __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-      _IF_ASAN() __annotate_increase(__n);
+      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
       pointer __p = __get_pointer() + __sz;
       for (; __first != __last; ++__p, (void)++__first)
         traits_type::assign(*__p, *__first);
@@ -2868,7 +2897,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
   size_type __cap = capacity();
   if (__cap - __sz >= __n) {
     if (__n) {
-      _IF_ASAN() __annotate_increase(__n);
+      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
       value_type* __p    = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __pos;
       if (__n_move != 0) {
@@ -2896,7 +2925,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
     size_type __cap = capacity();
     value_type* __p;
     if (__cap - __sz >= __n) {
-      _IF_ASAN() __annotate_increase(__n);
+      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
       __p                = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __pos;
       if (__n_move != 0)
@@ -2989,7 +3018,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
     __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
     __p = std::__to_address(__get_long_pointer());
   } else {
-    _IF_ASAN() __annotate_increase(1);
+    _LIBCPP_IF_ASAN() { __annotate_increase(1); }
     __p                = std::__to_address(__get_pointer());
     size_type __n_move = __sz - __ip;
     if (__n_move != 0)
@@ -3017,8 +3046,10 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
   if (__cap - __sz + __n1 >= __n2) {
     value_type* __p = std::__to_address(__get_pointer());
     if (__n1 != __n2) {
-      _IF_ASAN() if (__n2 > __n1)
-        __annotate_increase(__n2 - __n1);
+      _LIBCPP_IF_ASAN() {
+        if (__n2 > __n1)
+          __annotate_increase(__n2 - __n1);
+      }
       size_type __n_move = __sz - __pos - __n1;
       if (__n_move != 0) {
         if (__n1 > __n2) {
@@ -3060,8 +3091,10 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
   if (__cap - __sz + __n1 >= __n2) {
     __p = std::__to_address(__get_pointer());
     if (__n1 != __n2) {
-      _IF_ASAN() if (__n2 > __n1)
-        __annotate_increase(__n2 - __n1);
+      _LIBCPP_IF_ASAN() {
+        if (__n2 > __n1)
+          __annotate_increase(__n2 - __n1);
+      }
       size_type __n_move = __sz - __pos - __n1;
       if (__n_move != 0)
         traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
@@ -3183,7 +3216,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
     traits_type::assign(*__get_short_pointer(), value_type());
     __set_short_size(0);
   }
-  _IF_ASAN() __annotate_shrink(__old_size);
+  _LIBCPP_IF_ASAN() { __annotate_shrink(__old_size); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3236,7 +3269,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) {
-  _IF_ASAN() __annotate_delete();
+  _LIBCPP_IF_ASAN() { __annotate_delete(); }
   size_type __cap = capacity();
   size_type __sz  = size();
 
@@ -3282,7 +3315,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
     __set_long_pointer(__new_data);
   } else
     __set_short_size(__sz);
-  _IF_ASAN() __annotate_new(__sz);
+  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3324,16 +3357,20 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
       __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value ||
           __alloc() == __str.__alloc(),
       "swapping non-equal allocators");
-  _IF_ASAN() if (!__is_long())
-    __annotate_delete();
-  _IF_ASAN() if (this != &__str && !__str.__is_long())
-    __str.__annotate_delete();
+  _LIBCPP_IF_ASAN() {
+    if (!__is_long())
+      __annotate_delete();
+    if (this != &__str && !__str.__is_long())
+      __str.__annotate_delete();
+  }
   std::swap(__r_.first(), __str.__r_.first());
   std::__swap_allocator(__alloc(), __str.__alloc());
-  _IF_ASAN() if (!__is_long())
-    __annotate_new(__get_short_size());
-  _IF_ASAN() if (this != &__str && !__str.__is_long())
-    __str.__annotate_new(__str.__get_short_size());
+  _LIBCPP_IF_ASAN() {
+    if (!__is_long())
+      __annotate_new(__get_short_size());
+    if (this != &__str && !__str.__is_long())
+      __str.__annotate_new(__str.__get_short_size());
+  }
 }
 
 // find
@@ -3689,7 +3726,7 @@ template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT {
   clear();
   if (__is_long()) {
-    _IF_ASAN() __annotate_delete();
+    _LIBCPP_IF_ASAN() { __annotate_delete(); }
     __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
     __r_.first() = __rep();
   }

>From 739aa3e67c3e3ebc351682655b1f151af54ac6aa Mon Sep 17 00:00:00 2001
From: Advenam Tacet <advenam.tacet at trailofbits.com>
Date: Thu, 21 Dec 2023 19:03:57 +0100
Subject: [PATCH 3/4] Conditionalize ASan variables

Variables used only by ASan helper functions are conditionalized (put behind `#ifndef _LIBCPP_HAS_NO_ASAN`) after that commit.
That should remove any impact on performance.
---
 libcxx/include/string | 51 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index a32186e5abd80f..cc6efdb89025f8 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1368,7 +1368,9 @@ public:
   _LIBCPP_HIDE_FROM_ABI constexpr void __move_assign(basic_string&& __str, size_type __pos, size_type __len) {
     // Pilfer the allocation from __str.
     _LIBCPP_ASSERT_INTERNAL(__alloc() == __str.__alloc(), "__move_assign called with wrong allocator");
+#ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_sz = __str.size();
+#endif
     _LIBCPP_IF_ASAN() {
       if (!__str.__is_long())
         __str.__annotate_delete();
@@ -1382,11 +1384,13 @@ public:
     _Traits::assign(data()[__len], value_type());
 
     _LIBCPP_IF_ASAN() {
+#ifndef __LIBCPP_HAS_NO_ASAN
       if (!__is_long()) {
         __annotate_new(__len);
       } else if (__old_sz > __len) {
         __annotate_shrink(__old_sz);
       }
+#endif
     }
   }
 #endif
@@ -2091,35 +2095,43 @@ private:
 
   // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) {
+#ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_size = size();
     _LIBCPP_IF_ASAN() {
       if (__n > __old_size)
         __annotate_increase(__n - __old_size);
     }
+#endif
     pointer __p =
         __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer());
     traits_type::move(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
+#ifndef __LIBCPP_HAS_NO_ASAN
     _LIBCPP_IF_ASAN() {
       if (__old_size > __n)
         __annotate_shrink(__old_size);
     }
+#endif
     return *this;
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   __null_terminate_at(value_type* __p, size_type __newsz) {
+#ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_size = size();
     _LIBCPP_IF_ASAN() {
       if (__newsz > __old_size)
         __annotate_increase(__newsz - __old_size);
     }
+#endif
     __set_size(__newsz);
     traits_type::assign(__p[__newsz], value_type());
+#ifndef __LIBCPP_HAS_NO_ASAN
     _LIBCPP_IF_ASAN() {
       if (__old_size > __newsz)
         __annotate_shrink(__old_size);
     }
+#endif
     return *this;
   }
 
@@ -2463,19 +2475,23 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Al
 basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) {
   size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
   if (__n < __cap) {
+#ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_size = __is_short ? __get_short_size() : __get_long_size();
     _LIBCPP_IF_ASAN() {
       if (__n > __old_size)
         __annotate_increase(__n - __old_size);
     }
+#endif
     pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
     __is_short ? __set_short_size(__n) : __set_long_size(__n);
     traits_type::copy(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
+#ifndef __LIBCPP_HAS_NO_ASAN
     _LIBCPP_IF_ASAN() {
       if (__old_size > __n)
         __annotate_shrink(__old_size);
     }
+#endif
   } else {
     size_type __sz = __is_short ? __get_short_size() : __get_long_size();
     __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
@@ -2488,10 +2504,9 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Al
 basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) {
   size_type __cap = capacity();
   if (__cap >= __n) {
-    size_type __old_size = size();
     _LIBCPP_IF_ASAN() {
-      if (__n > __old_size)
-        __annotate_increase(__n - __old_size);
+      if (__n > size())
+        __annotate_increase(__n - size());
     }
     value_type* __p = std::__to_address(__get_pointer());
     traits_type::move(__p, __s, __n);
@@ -2514,14 +2529,13 @@ template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) {
   size_type __cap      = capacity();
-  size_type __old_size = size();
   if (__cap < __n) {
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
     _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
   } else _LIBCPP_IF_ASAN() {
-      if (__n > __old_size)
-        __annotate_increase(__n - __old_size);
+      if (__n > size())
+        __annotate_increase(__n - size());
     }
   value_type* __p = std::__to_address(__get_pointer());
   traits_type::assign(__p, __n, __c);
@@ -2532,11 +2546,13 @@ template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   pointer __p;
+#ifndef _LIBCPP_HAS_NO_ASAN
   size_type __old_size = size();
   _LIBCPP_IF_ASAN() {
     if (__old_size == 0)
       __annotate_increase(1);
   }
+#endif
   if (__is_long()) {
     __p = __get_long_pointer();
     __set_long_size(1);
@@ -2546,10 +2562,12 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   }
   traits_type::assign(*__p, __c);
   traits_type::assign(*++__p, value_type());
+#ifndef _LIBCPP_HAS_NO_ASAN
   _LIBCPP_IF_ASAN() {
     if (__old_size > 1)
       __annotate_shrink(__old_size);
   }
+#endif
   return *this;
 }
 
@@ -2560,16 +2578,20 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
     __copy_assign_alloc(__str);
     if (!__is_long()) {
       if (!__str.__is_long()) {
+#ifndef _LIBCPP_HAS_NO_ASAN
         size_type __old_size = __get_short_size();
+#endif
         _LIBCPP_IF_ASAN() {
           if (__get_short_size() < __str.__get_short_size())
             __annotate_increase(__str.__get_short_size() - __get_short_size());
         }
         __r_.first() = __str.__r_.first();
+#ifndef _LIBCPP_HAS_NO_ASAN
         _LIBCPP_IF_ASAN() {
           if (__old_size > __get_short_size())
             __annotate_shrink(__old_size);
         }
+#endif
       } else {
         return __assign_no_alias<true>(__str.data(), __str.size());
       }
@@ -2612,13 +2634,16 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
     }
 #  endif
   }
+#ifndef _LIBCPP_HAS_NO_ASAN
   size_type __str_old_size = __str.size();
+#endif
   bool __str_was_short     = !__str.__is_long();
 
   __move_assign_alloc(__str);
   __r_.first() = __str.__r_.first();
   __str.__set_short_size(0);
   traits_type::assign(__str.__get_short_pointer()[0], value_type());
+#ifndef _LIBCPP_HAS_NO_ASAN
   _LIBCPP_IF_ASAN() {
     if (__str_was_short && this != &__str)
       __str.__annotate_shrink(__str_old_size);
@@ -2638,6 +2663,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
       // If it is long string, delete was never called on original __str's buffer.
       __annotate_new(__get_short_size());
   }
+#endif
 }
 
 #endif
@@ -2678,8 +2704,9 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
 basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {
   _LIBCPP_ASSERT_INTERNAL(
       __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");
-
+#ifndef _LIBCPP_HAS_NO_ASAN
   size_type __old_size = size();
+#endif
   size_type __cap      = capacity();
   if (__cap < __n) {
     // Unlike `append` functions, if the input range points into the string itself, there is no case that the input
@@ -2692,18 +2719,20 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
     _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
   } else _LIBCPP_IF_ASAN() {
-    if (__n > __old_size)
-      __annotate_increase(__n - __old_size);
+    if (__n > size())
+      __annotate_increase(__n - size());
   }
   pointer __p = __get_pointer();
   for (; __first != __last; ++__p, (void)++__first)
     traits_type::assign(*__p, *__first);
   traits_type::assign(*__p, value_type());
   __set_size(__n);
+#ifndef _LIBCPP_HAS_NO_ASAN
   _LIBCPP_IF_ASAN() {
     if (__n < __old_size)
       __annotate_shrink(__old_size);
   }
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3208,7 +3237,9 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT {
+#ifndef _LIBCPP_HAS_NO_ASAN
   size_type __old_size = size();
+#endif
   if (__is_long()) {
     traits_type::assign(*__get_long_pointer(), value_type());
     __set_long_size(0);
@@ -3216,7 +3247,9 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
     traits_type::assign(*__get_short_pointer(), value_type());
     __set_short_size(0);
   }
+#ifndef _LIBCPP_HAS_NO_ASAN
   _LIBCPP_IF_ASAN() { __annotate_shrink(__old_size); }
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>

>From bd888d99ab73ea587fde0fa3db43191343f198a2 Mon Sep 17 00:00:00 2001
From: Advenam Tacet <advenam.tacet at trailofbits.com>
Date: Thu, 21 Dec 2023 21:22:10 +0100
Subject: [PATCH 4/4] Changes based on @ldionne code review

- Macro moved to from `__config` to `string` file.
- `_LIBCPP_IF_ASAN` -> `_LIBCPP_STRING_IF_ASAN`.
- No more check `#ifndef _LIBCPP_STRING_IF_ASAN` before defining macro.
---
 libcxx/include/__config |   9 ---
 libcxx/include/string   | 132 +++++++++++++++++++++-------------------
 2 files changed, 69 insertions(+), 72 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 1e09851d404353..438dbfeeb988c5 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1490,15 +1490,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
 #    define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
 #  endif
 
-// ASan related macros
-// _LIBCPP_IF_ASAN is used to removed ASan related code, whenever compiled without ASan.
-#ifndef _LIBCPP_IF_ASAN
-#  ifndef _LIBCPP_HAS_NO_ASAN
-#    define _LIBCPP_IF_ASAN() if _LIBCPP_CONSTEXPR (true)
-#  else
-#    define _LIBCPP_IF_ASAN() if _LIBCPP_CONSTEXPR (false)
-#  endif
-#endif
 
 #endif // __cplusplus
 
diff --git a/libcxx/include/string b/libcxx/include/string
index cc6efdb89025f8..e32dbdeea6684f 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -659,6 +659,12 @@ _LIBCPP_PUSH_MACROS
 #else
 #  define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
 #endif
+// _LIBCPP_STRING_IF_ASAN is used to removed ASan related code, whenever compiled without ASan.
+#if  !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUCTMENTED_WITH_ASAN)
+#  define _LIBCPP_STRING_IF_ASAN() if _LIBCPP_CONSTEXPR (true)
+#else
+#  define _LIBCPP_STRING_IF_ASAN() if _LIBCPP_CONSTEXPR (false)
+#endif
 #define _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED false
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -858,7 +864,7 @@ private:
       __set_long_pointer(__allocation);
       __set_long_size(__size);
     }
-    _LIBCPP_IF_ASAN() { __annotate_new(__size); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_new(__size); }
   }
 
   template <class _Iter, class _Sent>
@@ -880,7 +886,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
       _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
       : __r_(__value_init_tag(), __default_init_tag()) {
-    _LIBCPP_IF_ASAN() { __annotate_new(0); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_new(0); }
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
@@ -890,14 +896,14 @@ public:
       _NOEXCEPT
 #endif
       : __r_(__value_init_tag(), __a) {
-    _LIBCPP_IF_ASAN() { __annotate_new(0); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_new(0); }
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str)
       : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
     if (!__str.__is_long()) {
       __r_.first() = __str.__r_.first();
-      _LIBCPP_IF_ASAN() { __annotate_new(__get_short_size()); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_new(__get_short_size()); }
     } else
       __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
   }
@@ -907,7 +913,7 @@ public:
       : __r_(__default_init_tag(), __a) {
     if (!__str.__is_long()) {
       __r_.first() = __str.__r_.first();
-      _LIBCPP_IF_ASAN() { __annotate_new(__get_short_size()); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_new(__get_short_size()); }
     } else
       __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
   }
@@ -930,7 +936,7 @@ public:
       : __r_(std::move(__str.__r_)) {
 #endif
     __str.__r_.first() = __rep();
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       __str.__annotate_new(0);
       if (!__is_long())
         __annotate_new(size());
@@ -944,13 +950,13 @@ public:
     else {
       if (__libcpp_is_constant_evaluated())
         __r_.first() = __rep();
-      _LIBCPP_IF_ASAN() {
+      _LIBCPP_STRING_IF_ASAN() {
         if (!__str.__is_long())
           __str.__annotate_delete();
       }
       __r_.first()       = __str.__r_.first();
       __str.__r_.first() = __rep();
-      _LIBCPP_IF_ASAN() {
+      _LIBCPP_STRING_IF_ASAN() {
         __str.__annotate_new(0);
         if (!__is_long() && this != &__str)
           __annotate_new(size());
@@ -1112,7 +1118,7 @@ public:
 #endif // _LIBCPP_CXX03_LANG
 
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
-    _LIBCPP_IF_ASAN() { __annotate_delete(); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
     if (__is_long())
       __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
   }
@@ -1371,19 +1377,19 @@ public:
 #ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_sz = __str.size();
 #endif
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (!__str.__is_long())
         __str.__annotate_delete();
     }
     __r_.first()       = __str.__r_.first();
     __str.__r_.first() = __rep();
-    _LIBCPP_IF_ASAN() { __str.__annotate_new(0); }
+    _LIBCPP_STRING_IF_ASAN() { __str.__annotate_new(0); }
 
     _Traits::move(data(), data() + __pos, __len);
     __set_size(__len);
     _Traits::assign(data()[__len], value_type());
 
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
 #ifndef __LIBCPP_HAS_NO_ASAN
       if (!__is_long()) {
         __annotate_new(__len);
@@ -1821,7 +1827,7 @@ private:
     size_type __cap = capacity();
     value_type* __p;
     if (__cap - __sz >= __n) {
-      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
       __p                = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __ip;
       if (__n_move != 0)
@@ -2046,7 +2052,7 @@ private:
         __clear_and_shrink();
         __alloc() = __str.__alloc();
       } else {
-        _LIBCPP_IF_ASAN() { __annotate_delete(); }
+        _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
         allocator_type __a = __str.__alloc();
         auto __allocation  = std::__allocate_at_least(__a, __str.__get_long_cap());
         __begin_lifetime(__allocation.ptr, __allocation.count);
@@ -2056,7 +2062,7 @@ private:
         __set_long_pointer(__allocation.ptr);
         __set_long_cap(__allocation.count);
         __set_long_size(__str.size());
-        _LIBCPP_IF_ASAN() { __annotate_new(__get_long_size()); }
+        _LIBCPP_STRING_IF_ASAN() { __annotate_new(__get_long_size()); }
       }
     }
   }
@@ -2097,7 +2103,7 @@ private:
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) {
 #ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_size = size();
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__n > __old_size)
         __annotate_increase(__n - __old_size);
     }
@@ -2107,7 +2113,7 @@ private:
     traits_type::move(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
 #ifndef __LIBCPP_HAS_NO_ASAN
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__old_size > __n)
         __annotate_shrink(__old_size);
     }
@@ -2119,7 +2125,7 @@ private:
   __null_terminate_at(value_type* __p, size_type __newsz) {
 #ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_size = size();
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__newsz > __old_size)
         __annotate_increase(__newsz - __old_size);
     }
@@ -2127,7 +2133,7 @@ private:
     __set_size(__newsz);
     traits_type::assign(__p[__newsz], value_type());
 #ifndef __LIBCPP_HAS_NO_ASAN
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__old_size > __newsz)
         __annotate_shrink(__old_size);
     }
@@ -2225,7 +2231,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
   }
   traits_type::copy(std::__to_address(__p), __s, __sz);
   traits_type::assign(__p[__sz], value_type());
-  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2249,7 +2255,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
   }
   traits_type::copy(std::__to_address(__p), __s, __sz);
   traits_type::assign(__p[__sz], value_type());
-  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2273,7 +2279,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value
     __set_long_size(__sz);
   }
   traits_type::copy(std::__to_address(__p), __s, __sz + 1);
-  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2297,7 +2303,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   }
   traits_type::assign(std::__to_address(__p), __n, __c);
   traits_type::assign(__p[__n], value_type());
-  _LIBCPP_IF_ASAN() { __annotate_new(__n); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__n); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2312,7 +2318,7 @@ template <class _InputIterator, class _Sentinel>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
   __r_.first() = __rep();
-  _LIBCPP_IF_ASAN() { __annotate_new(0); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(0); }
 
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
@@ -2321,7 +2327,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator _
       push_back(*__first);
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
-    _LIBCPP_IF_ASAN() { __annotate_delete(); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
     if (__is_long())
       __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
     throw;
@@ -2374,7 +2380,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __fir
     throw;
   }
 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
-  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2392,7 +2398,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
-  _LIBCPP_IF_ASAN() { __annotate_delete(); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
   auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
   pointer __p       = __allocation.ptr;
   __begin_lifetime(__p, __allocation.count);
@@ -2411,7 +2417,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   __old_sz = __n_copy + __n_add + __sec_cp_sz;
   __set_long_size(__old_sz);
   traits_type::assign(__p[__old_sz], value_type());
-  _LIBCPP_IF_ASAN() { __annotate_new(__old_cap + __delta_cap); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__old_cap + __delta_cap); }
 }
 
 // __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
@@ -2435,7 +2441,7 @@ void _LIBCPP_CONSTEXPR_SINCE_CXX20
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
-  _LIBCPP_IF_ASAN() { __annotate_delete(); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
   auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
   pointer __p       = __allocation.ptr;
   __begin_lifetime(__p, __allocation.count);
@@ -2464,7 +2470,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
   __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
   _LIBCPP_SUPPRESS_DEPRECATED_POP
   __set_long_size(__old_sz - __n_del + __n_add);
-  _LIBCPP_IF_ASAN() { __annotate_new(__old_sz - __n_del + __n_add); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__old_sz - __n_del + __n_add); }
 }
 
 // assign
@@ -2477,7 +2483,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* _
   if (__n < __cap) {
 #ifndef __LIBCPP_HAS_NO_ASAN
     size_type __old_size = __is_short ? __get_short_size() : __get_long_size();
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__n > __old_size)
         __annotate_increase(__n - __old_size);
     }
@@ -2487,7 +2493,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* _
     traits_type::copy(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
 #ifndef __LIBCPP_HAS_NO_ASAN
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__old_size > __n)
         __annotate_shrink(__old_size);
     }
@@ -2504,7 +2510,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Al
 basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) {
   size_type __cap = capacity();
   if (__cap >= __n) {
-    _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() {
       if (__n > size())
         __annotate_increase(__n - size());
     }
@@ -2532,8 +2538,8 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
   if (__cap < __n) {
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
-    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
-  } else _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
+  } else _LIBCPP_STRING_IF_ASAN() {
       if (__n > size())
         __annotate_increase(__n - size());
     }
@@ -2548,7 +2554,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   pointer __p;
 #ifndef _LIBCPP_HAS_NO_ASAN
   size_type __old_size = size();
-  _LIBCPP_IF_ASAN() {
+  _LIBCPP_STRING_IF_ASAN() {
     if (__old_size == 0)
       __annotate_increase(1);
   }
@@ -2563,7 +2569,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
   traits_type::assign(*__p, __c);
   traits_type::assign(*++__p, value_type());
 #ifndef _LIBCPP_HAS_NO_ASAN
-  _LIBCPP_IF_ASAN() {
+  _LIBCPP_STRING_IF_ASAN() {
     if (__old_size > 1)
       __annotate_shrink(__old_size);
   }
@@ -2581,13 +2587,13 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
 #ifndef _LIBCPP_HAS_NO_ASAN
         size_type __old_size = __get_short_size();
 #endif
-        _LIBCPP_IF_ASAN() {
+        _LIBCPP_STRING_IF_ASAN() {
           if (__get_short_size() < __str.__get_short_size())
             __annotate_increase(__str.__get_short_size() - __get_short_size());
         }
         __r_.first() = __str.__r_.first();
 #ifndef _LIBCPP_HAS_NO_ASAN
-        _LIBCPP_IF_ASAN() {
+        _LIBCPP_STRING_IF_ASAN() {
           if (__old_size > __get_short_size())
             __annotate_shrink(__old_size);
         }
@@ -2623,28 +2629,28 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
 #  endif
 {
-  _LIBCPP_IF_ASAN() { __annotate_delete(); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
   if (__is_long()) {
     __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
 #  if _LIBCPP_STD_VER <= 14
     if (!is_nothrow_move_assignable<allocator_type>::value) {
       __set_short_size(0);
       traits_type::assign(__get_short_pointer()[0], value_type());
-      _LIBCPP_IF_ASAN() { __annotate_new(0); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_new(0); }
     }
 #  endif
   }
 #ifndef _LIBCPP_HAS_NO_ASAN
   size_type __str_old_size = __str.size();
-#endif
   bool __str_was_short     = !__str.__is_long();
+#endif
 
   __move_assign_alloc(__str);
   __r_.first() = __str.__r_.first();
   __str.__set_short_size(0);
   traits_type::assign(__str.__get_short_pointer()[0], value_type());
 #ifndef _LIBCPP_HAS_NO_ASAN
-  _LIBCPP_IF_ASAN() {
+  _LIBCPP_STRING_IF_ASAN() {
     if (__str_was_short && this != &__str)
       __str.__annotate_shrink(__str_old_size);
     else
@@ -2717,8 +2723,8 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _
     //    object itself stays valid even if reallocation happens.
     size_type __sz = size();
     __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
-    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
-  } else _LIBCPP_IF_ASAN() {
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
+  } else _LIBCPP_STRING_IF_ASAN() {
     if (__n > size())
       __annotate_increase(__n - size());
   }
@@ -2728,7 +2734,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _
   traits_type::assign(*__p, value_type());
   __set_size(__n);
 #ifndef _LIBCPP_HAS_NO_ASAN
-  _LIBCPP_IF_ASAN() {
+  _LIBCPP_STRING_IF_ASAN() {
     if (__n < __old_size)
       __annotate_shrink(__old_size);
   }
@@ -2783,7 +2789,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
   size_type __sz  = size();
   if (__cap - __sz >= __n) {
     if (__n) {
-      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
       value_type* __p = std::__to_address(__get_pointer());
       traits_type::copy(__p + __sz, __s, __n);
       __sz += __n;
@@ -2803,7 +2809,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
     size_type __sz  = size();
     if (__cap - __sz < __n)
       __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
     pointer __p = __get_pointer();
     traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
     __sz += __n;
@@ -2821,7 +2827,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
     size_type __sz  = size();
     if (__cap - __sz < __n)
       __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-    _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
     pointer __p = __get_pointer();
     __sz += __n;
     __set_size(__sz);
@@ -2843,10 +2849,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pu
   }
   if (__sz == __cap) {
     __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
-    _LIBCPP_IF_ASAN() { __annotate_increase(1); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(1); }
     __is_short = false; // the string is always long after __grow_by
   } else
-    _LIBCPP_IF_ASAN() { __annotate_increase(1); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(1); }
   pointer __p = __get_pointer();
   if (__is_short) {
     __p = __get_short_pointer() + __sz;
@@ -2870,7 +2876,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For
     if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
       if (__cap - __sz < __n)
         __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
       pointer __p = __get_pointer() + __sz;
       for (; __first != __last; ++__p, (void)++__first)
         traits_type::assign(*__p, *__first);
@@ -2926,7 +2932,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
   size_type __cap = capacity();
   if (__cap - __sz >= __n) {
     if (__n) {
-      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
       value_type* __p    = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __pos;
       if (__n_move != 0) {
@@ -2954,7 +2960,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
     size_type __cap = capacity();
     value_type* __p;
     if (__cap - __sz >= __n) {
-      _LIBCPP_IF_ASAN() { __annotate_increase(__n); }
+      _LIBCPP_STRING_IF_ASAN() { __annotate_increase(__n); }
       __p                = std::__to_address(__get_pointer());
       size_type __n_move = __sz - __pos;
       if (__n_move != 0)
@@ -3047,7 +3053,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
     __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
     __p = std::__to_address(__get_long_pointer());
   } else {
-    _LIBCPP_IF_ASAN() { __annotate_increase(1); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_increase(1); }
     __p                = std::__to_address(__get_pointer());
     size_type __n_move = __sz - __ip;
     if (__n_move != 0)
@@ -3075,7 +3081,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
   if (__cap - __sz + __n1 >= __n2) {
     value_type* __p = std::__to_address(__get_pointer());
     if (__n1 != __n2) {
-      _LIBCPP_IF_ASAN() {
+      _LIBCPP_STRING_IF_ASAN() {
         if (__n2 > __n1)
           __annotate_increase(__n2 - __n1);
       }
@@ -3120,7 +3126,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
   if (__cap - __sz + __n1 >= __n2) {
     __p = std::__to_address(__get_pointer());
     if (__n1 != __n2) {
-      _LIBCPP_IF_ASAN() {
+      _LIBCPP_STRING_IF_ASAN() {
         if (__n2 > __n1)
           __annotate_increase(__n2 - __n1);
       }
@@ -3248,7 +3254,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
     __set_short_size(0);
   }
 #ifndef _LIBCPP_HAS_NO_ASAN
-  _LIBCPP_IF_ASAN() { __annotate_shrink(__old_size); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_shrink(__old_size); }
 #endif
 }
 
@@ -3302,7 +3308,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) {
-  _LIBCPP_IF_ASAN() { __annotate_delete(); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
   size_type __cap = capacity();
   size_type __sz  = size();
 
@@ -3348,7 +3354,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
     __set_long_pointer(__new_data);
   } else
     __set_short_size(__sz);
-  _LIBCPP_IF_ASAN() { __annotate_new(__sz); }
+  _LIBCPP_STRING_IF_ASAN() { __annotate_new(__sz); }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3390,7 +3396,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
       __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value ||
           __alloc() == __str.__alloc(),
       "swapping non-equal allocators");
-  _LIBCPP_IF_ASAN() {
+  _LIBCPP_STRING_IF_ASAN() {
     if (!__is_long())
       __annotate_delete();
     if (this != &__str && !__str.__is_long())
@@ -3398,7 +3404,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
   }
   std::swap(__r_.first(), __str.__r_.first());
   std::__swap_allocator(__alloc(), __str.__alloc());
-  _LIBCPP_IF_ASAN() {
+  _LIBCPP_STRING_IF_ASAN() {
     if (!__is_long())
       __annotate_new(__get_short_size());
     if (this != &__str && !__str.__is_long())
@@ -3759,7 +3765,7 @@ template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT {
   clear();
   if (__is_long()) {
-    _LIBCPP_IF_ASAN() { __annotate_delete(); }
+    _LIBCPP_STRING_IF_ASAN() { __annotate_delete(); }
     __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
     __r_.first() = __rep();
   }



More information about the libcxx-commits mailing list