diff --git a/stl/inc/xstring b/stl/inc/xstring index 0ac07f32221..b49bb137779 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -580,6 +580,11 @@ concept _Contiguous_range_of = (_RANGES contiguous_range<_Rng>) && same_as>, _Ty>; #endif // _HAS_CXX23 +#pragma warning(push) +// Invalid annotation: 'NullTerminated' property may only be used on buffers whose elements are of integral or pointer +// type +#pragma warning(disable : 6510) + _EXPORT_STD template , class _Alloc = allocator<_Elem>> class basic_string { // null-terminated transparent array of elements private: @@ -3195,6 +3200,8 @@ private: _Compressed_pair<_Alty, _Scary_val> _Mypair; }; +#pragma warning(pop) + #if _HAS_CXX17 template >, enable_if_t, _Is_allocator<_Alloc>>, int> = 0> diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index dac4ec93ae0..edc4236ae50 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include #include @@ -1229,14 +1230,20 @@ static_assert(!is_constructible_v); static_assert(!is_assignable_v); #endif // _HAS_CXX23 -// Also test that no C6510 warning +// Also test that basic_string_view produces no C6510 warning +// when instantiated with custom character types. +// GH-5563: Extend coverage to basic_string struct char_wrapper { char c; }; template <> struct std::char_traits { - using char_type = char_wrapper; + using char_type = char_wrapper; + using int_type = int; + using pos_type = char_traits::pos_type; + using off_type = char_traits::off_type; + using state_type = char_traits::state_type; static bool eq(char_wrapper lhs, char_wrapper rhs) { return lhs.c == rhs.c; @@ -1247,18 +1254,76 @@ struct std::char_traits { return strlen(reinterpret_cast(a)); } + static char_wrapper* copy(char_wrapper* const first1, const char_wrapper* const first2, const size_t count) { + copy_n(first2, count, first1); + return first1; + } + + static char_wrapper* move(char_wrapper* const first1, const char_wrapper* const first2, const size_t count) { + memmove(first1, first2, count * sizeof(char_wrapper)); + return first1; + } + static int compare(const char_wrapper* lhs, const char_wrapper* rhs, size_t count) { return char_traits::compare( reinterpret_cast(lhs), reinterpret_cast(rhs), count); } -}; -using WrappedSV = basic_string_view>; + static const char_wrapper* find(const char_wrapper* first, size_t count, const char_wrapper& ch) { + for (; 0 < count; --count, ++first) { + if (eq(*first, ch)) { + return first; + } + } + + return nullptr; + } + + static char_wrapper* assign(char_wrapper* const first, size_t count, const char_wrapper ch) { + for (char_wrapper* next = first; count > 0; --count, ++next) { + *next = ch; + } + + return first; + } + + static void assign(char_wrapper& left, const char_wrapper& right) { + left = right; + } + + static bool lt(const char_wrapper left, const char_wrapper right) { + return char_traits::lt(left.c, right.c); + } + + static char_wrapper to_char_type(const int_type meta) { + return {char_traits::to_char_type(meta)}; + } + + static int_type to_int_type(const char_wrapper ch) { + return char_traits::to_int_type(ch.c); + } + + static bool eq_int_type(const int_type left, const int_type right) { + return char_traits::eq_int_type(left, right); + } + + static int_type not_eof(const int_type meta) { + return char_traits::not_eof(meta); + } + + static int_type eof() { + return char_traits::eof(); + } +}; void test_C6510_warning() { // compile-only char_wrapper a[] = {{'a'}, {'b'}, {'c'}, {'\0'}}; - WrappedSV sv(a); + basic_string_view sv(a); (void) sv; + + // GH-5563: Extend test coverage to basic_string + basic_string s(a); + (void) s; } #if _HAS_CXX20