//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// // // Make sure basic_string::insert does not cause infinite recursion. // This is a regression test for a bug that had been introduced in D98573. #include #include #include #include "test_macros.h" #include "asan_testing.h" struct char_ascii { char char_; char_ascii() = default; char_ascii(char ch) : char_(ch) { assert(ch <= 0x7f); } }; template <> struct std::char_traits { using char_type = char_ascii; using int_type = typename std::char_traits::int_type; using off_type = typename std::char_traits::off_type; using pos_type = typename std::char_traits::pos_type; using state_type = typename std::char_traits::state_type; static void assign(char_type& r, char_type const& a) TEST_NOEXCEPT { r = a; } static char_type* assign(char_type* p, std::size_t count, char_type a) { std::fill(p, p + count, a); return p; } static bool eq(char_type a, char_type b) TEST_NOEXCEPT { return a.char_ == b.char_; } static bool lt(char_type a, char_type b) TEST_NOEXCEPT { return a.char_ < b.char_; } static std::size_t length(char_type const* s) { std::size_t n = 0; if (s) { while (s->char_) ++n; } return n; } static const char_type* find(char_type const* p, std::size_t count, char_type const& ch) { while (count > 0) { if (p->char_ == ch.char_) { return p; } else { ++p; --count; } } return nullptr; } static int compare(char_type const* s1, char_type const* s2, std::size_t count) { for (std::size_t i = 0; i < count; ++i) { if (s1->char_ < s2->char_) return -1; else if (s2->char_ < s1->char_) return 1; } return 0; } static char_type* move(char_type* dest, char_type const* src, std::size_t count) { if (src <= dest && dest < src + count) { std::copy_backward(src, src + count, dest + count); } else { std::copy(src, src + count, dest); } return dest; } static char_type* copy(char_type* dest, char_type const* src, std::size_t count) { return char_traits::move(dest, src, count); } }; int main(int, char**) { std::basic_string str; char_ascii ch('A'); str.insert(str.begin(), &ch, &ch + 1); assert(str.size() == 1); assert(str[0].char_ == 'A'); LIBCPP_ASSERT(is_string_asan_correct(str)); return 0; }