[libcxx-commits] [libcxx] [llvm] [libcxx] Remove ASan container overflow checks for SSO strings (PR #194208)

Aiden Grossman via libcxx-commits libcxx-commits at lists.llvm.org
Sat Apr 25 23:23:02 PDT 2026


https://github.com/boomanaiden154 created https://github.com/llvm/llvm-project/pull/194208

Essentially a revert of #79536, although manual given how much the code has changed.

Doing container overflow checks on SSO strings interacts very poorly with a lot of compiler optimizations, which assume that the entire object is dereferencable when it is live. LLVM can sometimes insert speculative loads that will create false positives when they try and load a partially filled SSO buffer. This was previously prevented using inline asm barriers within std::string itself. However, this can also manifest in other ways, with the motivating example for the revert being GlobalOpt inserting a speculative load of a std::variant containing a SSO std::string, causing an ASan failure.

>From 7896f5bcde5401964f8111764e49354bd21ea0df Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Sun, 26 Apr 2026 06:18:03 +0000
Subject: [PATCH] [libcxx] Remove ASan container overflow checks for SSO
 strings

Essentially a revert of #79536, although manual given how much the code
has changed.

Doing container overflow checks on SSO strings interacts very poorly
with a lot of compiler optimizations, which assume that the entire
object is dereferencable when it is live. LLVM can sometimes insert
speculative loads that will create false positives when they try and
load a partially filled SSO buffer. This was previously prevented using
inline asm barriers within std::string itself. However, this can also
manifest in other ways, with the motivating example for the revert being
GlobalOpt inserting a speculative load of a std::variant containing a
SSO std::string, causing an ASan failure.
---
 libcxx/include/string                         |  30 ---
 .../asan_deque_integration.pass.cpp           | 182 ------------------
 .../strings/basic.string/asan_short.pass.cpp  |  56 ------
 .../asan_vector_integration.pass.cpp          | 182 ------------------
 libcxx/test/support/asan_testing.h            |  29 ++-
 .../Inputs/test-dwarf-clang-unspec-params.elf | Bin 16800 -> 0 bytes
 6 files changed, 24 insertions(+), 455 deletions(-)
 delete mode 100644 libcxx/test/libcxx/strings/basic.string/asan_deque_integration.pass.cpp
 delete mode 100644 libcxx/test/libcxx/strings/basic.string/asan_short.pass.cpp
 delete mode 100644 libcxx/test/libcxx/strings/basic.string/asan_vector_integration.pass.cpp
 delete mode 100755 llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf

diff --git a/libcxx/include/string b/libcxx/include/string
index 0c8767df2cdd2..d2551beb12045 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -759,20 +759,10 @@ public:
   //
   // This string implementation doesn't contain any references into itself. It only contains a bit that says whether
   // it is in small or large string mode, so the entire structure is trivially relocatable if its members are.
-#  if _LIBCPP_ENABLE_ASAN_CONTAINER_CHECKS_FOR_STRING
-  // When compiling with AddressSanitizer (ASan), basic_string cannot be trivially
-  // relocatable. Because the object's memory might be poisoned when its content
-  // is kept inside objects memory (short string optimization), instead of in allocated
-  // external memory. In such cases, the destructor is responsible for unpoisoning
-  // the memory to avoid triggering false positives.
-  // Therefore it's crucial to ensure the destructor is called.
-  using __trivially_relocatable _LIBCPP_NODEBUG = void;
-#  else
   using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
       __libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value,
       basic_string,
       void>;
-#  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");
@@ -2185,7 +2175,6 @@ 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_;
   }
 
@@ -2195,7 +2184,6 @@ 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_;
   }
 
@@ -2208,31 +2196,26 @@ 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");
-    __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");
-    __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 {
-    __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 {
-    __annotate_memory_barrier();
     return pointer_traits<const_pointer>::pointer_to(__rep_.__s.__data_[0]);
   }
 
@@ -2308,25 +2291,12 @@ private:
     (void)__old_mid;
     (void)__new_mid;
 #  if _LIBCPP_ENABLE_ASAN_CONTAINER_CHECKS_FOR_STRING
-#    if defined(__APPLE__)
-    // TODO: remove after addressing issue #96099 (https://llvm.org/PR96099)
     if (!__is_long())
       return;
-#    endif
     std::__annotate_contiguous_container<_Allocator>(data(), data() + capacity() + 1, __old_mid, __new_mid);
 #  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);
   }
diff --git a/libcxx/test/libcxx/strings/basic.string/asan_deque_integration.pass.cpp b/libcxx/test/libcxx/strings/basic.string/asan_deque_integration.pass.cpp
deleted file mode 100644
index 1205190b3a6e1..0000000000000
--- a/libcxx/test/libcxx/strings/basic.string/asan_deque_integration.pass.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: asan
-// UNSUPPORTED: c++03
-
-#include <cassert>
-#include <string>
-#include <array>
-#include <deque>
-#include "test_macros.h"
-#include "asan_testing.h"
-#include "min_allocator.h"
-
-// This tests exists to check if strings work well with deque, as those
-// may be partialy annotated, we cannot simply call
-// is_double_ended_contiguous_container_asan_correct, as it assumes that
-// object memory inside is not annotated, so we check everything in a more careful way.
-
-template <typename D>
-void verify_inside(D const& d) {
-  for (size_t i = 0; i < d.size(); ++i) {
-    assert(is_string_asan_correct(d[i]));
-  }
-}
-
-template <typename S, size_t N>
-S get_s(char c) {
-  S s;
-  for (size_t i = 0; i < N; ++i)
-    s.push_back(c);
-
-  return s;
-}
-
-template <class C, class S>
-void test_string() {
-  size_t const N = sizeof(S) < 256 ? (4096 / sizeof(S)) : 16;
-
-  {
-    C d1a(1), d1b(N), d1c(N + 1), d1d(5 * N);
-    verify_inside(d1a);
-    verify_inside(d1b);
-    verify_inside(d1c);
-    verify_inside(d1d);
-  }
-  {
-    C d2;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      d2.push_back(get_s<S, 1>(i % 10 + 'a'));
-      verify_inside(d2);
-      d2.push_back(get_s<S, 22>(i % 10 + 'b'));
-      verify_inside(d2);
-
-      d2.pop_front();
-      verify_inside(d2);
-    }
-  }
-  {
-    C d3;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      d3.push_front(get_s<S, 1>(i % 10 + 'a'));
-      verify_inside(d3);
-      d3.push_front(get_s<S, 28>(i % 10 + 'b'));
-      verify_inside(d3);
-
-      d3.pop_back();
-      verify_inside(d3);
-    }
-  }
-  {
-    C d4;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      // When there is no SSO, all elements inside should not be poisoned,
-      // so we can verify deque poisoning.
-      d4.push_front(get_s<S, 33>(i % 10 + 'a'));
-      verify_inside(d4);
-      assert(is_double_ended_contiguous_container_asan_correct(d4));
-      d4.push_back(get_s<S, 28>(i % 10 + 'b'));
-      verify_inside(d4);
-      assert(is_double_ended_contiguous_container_asan_correct(d4));
-    }
-  }
-  {
-    C d5;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      // In d4 we never had poisoned memory inside deque.
-      // Here we start with SSO, so part of the inside of the container,
-      // will be poisoned.
-      d5.push_front(S());
-      verify_inside(d5);
-    }
-    for (size_t i = 0; i < d5.size(); ++i) {
-      // We change the size to have long string.
-      // Memory owne by deque should not be poisoned by string.
-      d5[i].resize(100);
-      verify_inside(d5);
-    }
-
-    assert(is_double_ended_contiguous_container_asan_correct(d5));
-
-    d5.erase(d5.begin() + 2);
-    verify_inside(d5);
-
-    d5.erase(d5.end() - 2);
-    verify_inside(d5);
-
-    assert(is_double_ended_contiguous_container_asan_correct(d5));
-  }
-  {
-    C d6a;
-    assert(is_double_ended_contiguous_container_asan_correct(d6a));
-
-    C d6b(N + 2, get_s<S, 100>('a'));
-    d6b.push_front(get_s<S, 101>('b'));
-    while (!d6b.empty()) {
-      d6b.pop_back();
-      assert(is_double_ended_contiguous_container_asan_correct(d6b));
-    }
-
-    C d6c(N + 2, get_s<S, 102>('c'));
-    while (!d6c.empty()) {
-      d6c.pop_back();
-      assert(is_double_ended_contiguous_container_asan_correct(d6c));
-    }
-  }
-  {
-    C d7(9 * N + 2);
-
-    d7.insert(d7.begin() + 1, S());
-    verify_inside(d7);
-
-    d7.insert(d7.end() - 3, S());
-    verify_inside(d7);
-
-    d7.insert(d7.begin() + 2 * N, get_s<S, 1>('a'));
-    verify_inside(d7);
-
-    d7.insert(d7.end() - 2 * N, get_s<S, 1>('b'));
-    verify_inside(d7);
-
-    d7.insert(d7.begin() + 2 * N, 3 * N, get_s<S, 1>('c'));
-    verify_inside(d7);
-
-    // It may not be short for big element types, but it will be checked correctly:
-    d7.insert(d7.end() - 2 * N, 3 * N, get_s<S, 2>('d'));
-    verify_inside(d7);
-
-    d7.erase(d7.begin() + 2);
-    verify_inside(d7);
-
-    d7.erase(d7.end() - 2);
-    verify_inside(d7);
-  }
-}
-
-template <class S>
-void test_container() {
-  test_string<std::deque<S, std::allocator<S>>, S>();
-  test_string<std::deque<S, min_allocator<S>>, S>();
-  test_string<std::deque<S, safe_allocator<S>>, S>();
-}
-
-int main(int, char**) {
-  // Those tests support only types based on std::basic_string.
-  test_container<std::string>();
-  test_container<std::wstring>();
-#if TEST_STD_VER >= 11
-  test_container<std::u16string>();
-  test_container<std::u32string>();
-#endif
-#if TEST_STD_VER >= 20
-  test_container<std::u8string>();
-#endif
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/strings/basic.string/asan_short.pass.cpp b/libcxx/test/libcxx/strings/basic.string/asan_short.pass.cpp
deleted file mode 100644
index 5140f429216fc..0000000000000
--- a/libcxx/test/libcxx/strings/basic.string/asan_short.pass.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: libcpp-instrumented-with-asan
-// UNSUPPORTED: c++03
-
-// <string>
-
-// Basic test if ASan annotations work for short strings.
-
-#include <string>
-#include <cassert>
-#include <cstdlib>
-
-#include "asan_testing.h"
-#include "min_allocator.h"
-#include "test_iterators.h"
-#include "test_macros.h"
-
-extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
-
-void do_exit() { exit(0); }
-
-int main(int, char**) {
-  {
-    typedef cpp17_input_iterator<char*> MyInputIter;
-    // Should not trigger ASan.
-    std::basic_string<char, std::char_traits<char>, safe_allocator<char>> v;
-    char i[] = {'a', 'b', 'c', 'd'};
-
-    v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 4));
-    assert(v[0] == 'a');
-    assert(is_string_asan_correct(v));
-  }
-
-  __sanitizer_set_death_callback(do_exit);
-  {
-    using T     = char;
-    using C     = std::basic_string<T, std::char_traits<T>, safe_allocator<T>>;
-    const T t[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
-    C c(std::begin(t), std::end(t));
-    assert(is_string_asan_correct(c));
-    assert(__sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) !=
-           0);
-    volatile T foo = c[c.size() + 1]; // should trigger ASAN. Use volatile to prevent being optimized away.
-    assert(false);                    // if we got here, ASAN didn't trigger
-    ((void)foo);
-  }
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/strings/basic.string/asan_vector_integration.pass.cpp b/libcxx/test/libcxx/strings/basic.string/asan_vector_integration.pass.cpp
deleted file mode 100644
index b7d95b7069083..0000000000000
--- a/libcxx/test/libcxx/strings/basic.string/asan_vector_integration.pass.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: asan
-// UNSUPPORTED: c++03
-
-#include <cassert>
-#include <string>
-#include <vector>
-#include <array>
-#include "test_macros.h"
-#include "asan_testing.h"
-#include "min_allocator.h"
-
-// This tests exists to check if strings work well with vector, as those
-// may be partialy annotated, we cannot simply call
-// is_contiguous_container_asan_correct, as it assumes that
-// object memory inside is not annotated, so we check everything in a more careful way.
-
-template <typename D>
-void verify_inside(D const& d) {
-  for (size_t i = 0; i < d.size(); ++i) {
-    assert(is_string_asan_correct(d[i]));
-  }
-}
-
-template <typename S, size_t N>
-S get_s(char c) {
-  S s;
-  for (size_t i = 0; i < N; ++i)
-    s.push_back(c);
-
-  return s;
-}
-
-template <class C, class S>
-void test_string() {
-  size_t const N = sizeof(S) < 256 ? (4096 / sizeof(S)) : 16;
-
-  {
-    C d1a(1), d1b(N), d1c(N + 1), d1d(5 * N);
-    verify_inside(d1a);
-    verify_inside(d1b);
-    verify_inside(d1c);
-    verify_inside(d1d);
-  }
-  {
-    C d2;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      d2.push_back(get_s<S, 1>(i % 10 + 'a'));
-      verify_inside(d2);
-      d2.push_back(get_s<S, 28>(i % 10 + 'b'));
-      verify_inside(d2);
-
-      d2.erase(d2.cbegin());
-      verify_inside(d2);
-    }
-  }
-  {
-    C d3;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      d3.push_back(get_s<S, 1>(i % 10 + 'a'));
-      verify_inside(d3);
-      d3.push_back(get_s<S, 28>(i % 10 + 'b'));
-      verify_inside(d3);
-
-      d3.pop_back();
-      verify_inside(d3);
-    }
-  }
-  {
-    C d4;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      // When there is no SSO, all elements inside should not be poisoned,
-      // so we can verify vector poisoning.
-      d4.push_back(get_s<S, 33>(i % 10 + 'a'));
-      verify_inside(d4);
-      assert(is_contiguous_container_asan_correct(d4));
-      d4.push_back(get_s<S, 28>(i % 10 + 'b'));
-      verify_inside(d4);
-      assert(is_contiguous_container_asan_correct(d4));
-    }
-  }
-  {
-    C d5;
-    for (size_t i = 0; i < 3 * N + 2; ++i) {
-      // In d4 we never had poisoned memory inside vector.
-      // Here we start with SSO, so part of the inside of the container,
-      // will be poisoned.
-      d5.push_back(S());
-      verify_inside(d5);
-    }
-    for (size_t i = 0; i < d5.size(); ++i) {
-      // We change the size to have long string.
-      // Memory owne by vector should not be poisoned by string.
-      d5[i].resize(100);
-      verify_inside(d5);
-    }
-
-    assert(is_contiguous_container_asan_correct(d5));
-
-    d5.erase(d5.begin() + 2);
-    verify_inside(d5);
-
-    d5.erase(d5.end() - 2);
-    verify_inside(d5);
-
-    assert(is_contiguous_container_asan_correct(d5));
-  }
-  {
-    C d6a;
-    assert(is_contiguous_container_asan_correct(d6a));
-
-    C d6b(N + 2, get_s<S, 100>('a'));
-    d6b.push_back(get_s<S, 101>('b'));
-    while (!d6b.empty()) {
-      d6b.pop_back();
-      assert(is_contiguous_container_asan_correct(d6b));
-    }
-
-    C d6c(N + 2, get_s<S, 102>('c'));
-    while (!d6c.empty()) {
-      d6c.pop_back();
-      assert(is_contiguous_container_asan_correct(d6c));
-    }
-  }
-  {
-    C d7(9 * N + 2);
-
-    d7.insert(d7.begin() + 1, S());
-    verify_inside(d7);
-
-    d7.insert(d7.end() - 3, S());
-    verify_inside(d7);
-
-    d7.insert(d7.begin() + 2 * N, get_s<S, 1>('a'));
-    verify_inside(d7);
-
-    d7.insert(d7.end() - 2 * N, get_s<S, 1>('b'));
-    verify_inside(d7);
-
-    d7.insert(d7.begin() + 2 * N, 3 * N, get_s<S, 1>('c'));
-    verify_inside(d7);
-
-    // It may not be short for big element types, but it will be checked correctly:
-    d7.insert(d7.end() - 2 * N, 3 * N, get_s<S, 2>('d'));
-    verify_inside(d7);
-
-    d7.erase(d7.begin() + 2);
-    verify_inside(d7);
-
-    d7.erase(d7.end() - 2);
-    verify_inside(d7);
-  }
-}
-
-template <class S>
-void test_container() {
-  test_string<std::vector<S, std::allocator<S>>, S>();
-  test_string<std::vector<S, min_allocator<S>>, S>();
-  test_string<std::vector<S, safe_allocator<S>>, S>();
-}
-
-int main(int, char**) {
-  // Those tests support only types based on std::basic_string.
-  test_container<std::string>();
-  test_container<std::wstring>();
-#if TEST_STD_VER >= 11
-  test_container<std::u16string>();
-  test_container<std::u32string>();
-#endif
-#if TEST_STD_VER >= 20
-  test_container<std::u8string>();
-#endif
-
-  return 0;
-}
diff --git a/libcxx/test/support/asan_testing.h b/libcxx/test/support/asan_testing.h
index 2400befe99bde..ebddafa5035a3 100644
--- a/libcxx/test/support/asan_testing.h
+++ b/libcxx/test/support/asan_testing.h
@@ -56,16 +56,35 @@ TEST_CONSTEXPR bool is_double_ended_contiguous_container_asan_correct(const std:
 #endif
 
 #if TEST_HAS_FEATURE(address_sanitizer) && _LIBCPP_ENABLE_ASAN_CONTAINER_CHECKS_FOR_STRING
+template <typename S>
+bool is_string_short(S const& s) {
+  // We do not have access to __is_long(), but we can check if strings
+  // buffer is inside strings memory. If strings memory contains its content,
+  // SSO is in use. To check it, we can just confirm that the beginning is in
+  // the string object memory block.
+  // &s    - beginning of objects memory
+  // &s[0] - beginning of the buffer
+  // (&s+1) - end of objects memory
+  return (void*)std::addressof(s) <= (void*)std::addressof(s[0]) &&
+         (void*)std::addressof(s[0]) < (void*)(std::addressof(s) + 1);
+}
+
 template <typename ChrT, typename TraitsT, typename Alloc>
 TEST_CONSTEXPR bool is_string_asan_correct(const std::basic_string<ChrT, TraitsT, Alloc>& c) {
   if (TEST_IS_CONSTANT_EVALUATED)
     return true;
 
-  if (std::__asan_annotate_container_with_allocator<Alloc>::value)
-    return __sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) != 0;
-  else
-    return __sanitizer_verify_contiguous_container(
-               c.data(), c.data() + c.capacity() + 1, c.data() + c.capacity() + 1) != 0;
+  if (!is_string_short(c)) {
+    if (std::__asan_annotate_container_with_allocator<Alloc>::value)
+      return __sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) !=
+             0;
+    else
+      return __sanitizer_verify_contiguous_container(
+                 c.data(), c.data() + c.capacity() + 1, c.data() + c.capacity() + 1) != 0;
+  } else {
+    return __sanitizer_verify_contiguous_container(std::addressof(c), std::addressof(c) + 1, std::addressof(c) + 1) !=
+           0;
+  }
 }
 #else
 #  include <string>
diff --git a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf b/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf
deleted file mode 100755
index 67c6e71fbf7b93f456b519d2b75f72a7d6b64fb7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 16800
zcmeHOYitzP6~43Uwbw6fu)!uEJR}%_sK;Idj+0<mV;go=^N2C!AtjUb?%H0--gS1z
z$e at VO(ELD%ivDRURjnGefBL6ss#I$Gqg_gs7Nx0(+DcUF5BGse(nmm{6-^|z-<dgQ
zJq+upZKSGF=UOx0Ip?15-ZN+JyuA0mI5N5~plM1<Q0-Qv>CKKM$`y<KEC8aaUo~R?
zn0i!IL$9)JPJPq?)H>xx;6V(tJqRRTI|&tVy<=8_5+Nb+mMs(z6+u1@;)Tf0x)+af
z2ZB;x?oTH&if- at Ac$rl}H;+PC>~b6y2Oh*8&PzX|@JJ=zZRXu(p5S$kQ&93rIiane
z^XWw$byReFuauW}oOxaxW`9BIgUXScR_Z_L?=bTkbh{bl#Z8V`2}*xYgD0nyT|N at z
zG>>tA%bf?E^DoHhRoye0iM}1(GpVkbOm=>uYoWidt8a%<$QiwMzZ4hsL1SwF!J{g0
zP8G=}e3DzSQCg|~_{*j4FSWf{8&9 at npKIv))55M@)zSuW$cGBqXp=&9vWe|q!F_Og
zw1Ok`vZ{iejzzCvr at kxMKe3Emnda1NE^8L7MBXw at WyZ%3n5lF=J(Vd~>HPSCp_yDZ
zJ)W4DNjr6wYs}<A!ko-x6Em4Ja5Ql?lHBHOB9m3n3sx$*Z5y4DK2m4P(o_<zq(#V{
zbnN>_<9mn9USs<XC1S6!lMXn5bEMgSq-oGU3zYHm`sY56VHZ?iWZV2BnOfp}jhs>B
zx|Zvyd8K2&#n-Lai`-y1>eP!}^x_`JPGg*MF6E~#yWA?M?z+p)m#$5@;j+8O(W1+4
z-v^}wAN>sY8SpdUXTZ;Zp8-Dueg^)pGVp%Wh7V%r{~V583|;G1D)w^G3Y4zL&i^=k
z)y at OeNB$DO at b<H at 3%`q<|HJLW<0Fw`<XY^~z#TZ0R-Xs!?xfMw at fq76_U}<UmqOnr
zc;cS58ck1f)3v3=rjB#uc$E?U7i|BXFA;3LAG>fncIB^oVpr}3W7-?Bx9?l6XkaHd
z5H2lFHgyay at hQG@10$$b^V^Tc&JVn6K#X0uX*I?!4s3?KwE6~2x00n&>5b5O7_?`u
zF2#Fwa!GFLh$?FDohkToe37Edxv2vOHt^O8rG7AoUcOHsc#+~eH{f2*V>xrE^NXJW
zKLdUS{0#UR at H60Nz|Vl60Y3wN2K)^88TcQ`0R7(8ne0qaING}4Q#z1-PinngD(xb?
zQ!0%EHvwlz$3{gvGp4kKW^G+VP53f?up&GCR)77yQfV_e4A<Ddc#(Yvw(p`n_wQ6x
zIg0IDu(t#K;%C6mfS&<B1AYel4EP!FGvH^y&w!r+KLZ~x12P{`<{!%3!YOW6^iv-F
zoJXfQkyIKSC{K`VWIe|79 at nxi^CH)=F7q89VO{1&%KUDr|J(gij$FRVAB!?q at i0$j
zr1_Clid<jksOnY5dPe!CT+O;b4GU3jSo$rp9g{olBK!|aPCPK$uJ>7QW<GxUwd0jM
z;&ay4oyq1({eyM)w=Z|`Uj>;zzFem=4|V_0(3AQW%tqd-N46WiMnv!J>D}Jb-xE>E
znM8I<Kb6iGGP$fC=`(sT^Y$Pb3 at OddjixrT1S3tWb#mrN+Oc4j(r6ZHP&-<!v>`}U
zDijJ;RmULK9KbGAQ?049B%qyVfp&{M5KdwXXmnC&3v^+pssgX5;1eY5#V({my8+d~
zYOSU!TobmPwPRrwT!6WD8oNN9_Ov!!r;P`i2bHQ1AquK%cmcacRb3ORT0zYzZKc-P
z*%AtN=G&Uv)^)C2x2n3(2D+h<7;QhZHrpBOe6s$j`gqG84ESJ31=_`ca45vkCKc at 5
zU0;v!Sly)JEjYr>HZ0rv4pdW{0nme*MwF_Jusx0 at LJqfjsnHq|>+5%;GQ1R*1VK^N
z#<Uk(UeeZnTEjJ17e|O^(Q>_^Ed{@8Ejc!X?7$i+>=jO|>Qi(G81au&IyCLW6^#Tm
z$gx4_u*Z8)>j*T3HfZ*>@SFF)Ss!j}{a{<m&pZG4+V5Y%1zQ`?`L>{i0(GqcOtjYi
zy_Riy;X8MYw^pCMd;MpZtW_J%{K#&(hg)t9)z-BjXPQ=Ve4a{R?s&m6l5=ya+nSwI
z=E+FUWG-jU<uh4p^6)2<XVj9aV1t^UO;{>9oyaSiY;JQ+b8u{I at Pv6JesaVdKXG^j
zbKC8i=yXG*Ov#bb4UP0F9RiBPImGeWLAawTcd-fHd{<F)+uDeY{*^{!au^$3CWo+X
z!6ts=kjani&tP-=KM#G`Lg%ka-6?q;=zd<wPJWf_YwQM^%Ii366}zq2G}WTK_Z?b2
zq2cgu at qBdgr-N%&YgBVoEDrt(pu?^_b~@md3NvwZ2q+j6cA>jQrF9RdVPA!(mz)k7
z>{RG(vof$o$^FkZVs{Z6`O9gQ`}bGK9%xkZyc7Sg+y0_0;je8w+Tr>C_Wwp<yF&H=
zu3oka<0lX(9&a9g0XyZ#n}<c)-lp245M1RZ<Yv|OP&;>E*Ij-hHfoja>zA>sibL2m
z@#HW^V&=ZF!2=^^Y<NtW!zT_79*7SqbN}d}y at R9Xp?&*~jEtM(gL_9uus$T6N>~Xj
z1v!M}9jQ##oG+wPSn%Oq{}FYs*sw1;(@Yg|=5!*PqGcoxU(vL5B=hjHk#a*=1!BU(
zf(urpm?H;=X{m}yp*X8d5LcGMm?#v)@KFm{Dy(^_xUNMRh10WEVghL89h?>kx1Mx<
zP8r#pl{Tib^Tu30H<!*^r(LFr`3zPhWm0S!+#Bz*5>v`{pH38}m61A~MHdcQd8dXS
z*$*ft>hkHC1QC>B=fbek3zjnM)EW7leO`?8v^kki%%;uh6d0m83^S3>ClDSnL`HLo
z*-R3B<<J&(#@q}9r!izx8Ohx2Y#O&&BbA<*pTcRF%!!<sn8>G3iH3z&X_1j65fdqj
z#37Rl&QDo~Xyzs-3u&t$1N&nly}#lT!0U`t+WAHxDDSUaZTpH$_!u^N=M;WF^96O(
zxl7osK<>ll<{xLiAU!nPMec)Qi$iepUtqqVE{=>|{xR79j(1pzU*5|F<@n{j+#7!a
zeB9;A$1m^gf|t2pijndxe7QeoV55+wfB6m&d=+)>LT$JUJp}0;UHIiECqF^udq(0H
zKS6pv&^y2A^4>2<FQ-(z at jF(fE<vE23O~yI3KrQ>`u86H7f?^fB=zOz1wS|B`-+<>
zKL<tsvWKrTPjHJTVO%YAd!3uRe|hc+())tDc*oB-P)U3_ex<WFV=b!!UjA#SaPu3O
zC%8$7j9&f^J^UW#3qHp at 0m;AU*C606!ybcVlkZwtPwMp-U69^inp}MO?!DDTtu2jr
zM_bZ`|65ehx#!Ea{5~b?gJm5sjXx^Flk at m4Y?MFY%R0kiH+efRlaA!<g)jIX%x=EC
zx7}jCT&L28 at C5I9_$tbtJq}8oY%Rwx`h5u0mc%dbMa|5Ye#D<*b(bIvWMlVomGHfG
z;R`k}zf5Ey%EVuKDugHI_GS335yyk#a~F at QHZQ|(qZetE*BvPDz5HJ0dyn%?=ASAv
z9YOel1I+ihsln}z#oMm%#6Qk_uix{`m;VQezwiZ5Fkk8gFEXD#fZRoRVk5nL?-3(#
wk@?5DawBYX4as<taZUFp8G8`RrJo+mD1Dv|Ju1FYD)Y1SWsNf9A$U~vPgc_ET>t<8




More information about the libcxx-commits mailing list