Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions stl/src/vector_algorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6321,7 +6321,7 @@ namespace {
} else if (_Count1 < 96) {
return _Count2 >= 8;
} else {
return _Count2 >= 4;
return _Count2 >= 4; // if these thresholds are adjusted, review test_gh_6342_find_first_of()
}
} else if constexpr (sizeof(_Ty) == 4) {
if (_Count1 < 32) {
Expand Down Expand Up @@ -6390,9 +6390,7 @@ namespace {
return _Ix;
}
}

++_Ix;
} while (_Ix != _Haystack_length);
} while (++_Ix != _Haystack_length);
}

return static_cast<size_t>(-1);
Expand Down
39 changes: 39 additions & 0 deletions tests/std/tests/VSO_0000000_vector_algorithms/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,44 @@ void test_gh_5757_find_first_of() {
assert(pos == 0);
}

// GH-6342 <string>: wstring::find_first_of infinite-loops on ARM64
void test_gh_6342_find_first_of() {
const wstring needle{L"abcd"}; // Important size: 4-element needle
wstring haystack(150, L'x'); // Important size: 150-element haystack

// See _Find_meow_of::_Bitmap_impl::_Use_bitmap_neon() in vector_algorithms.cpp.
// For 2-byte wchar_t, when the haystack is >= 96 elements and the needle is >= 4 elements, the bitmap is used.
// The vectorized code consumes 16-element chunks. 150 % 16 is 6, so the scalar tail is [144, 150).
// No matching elements are present in [0, 144), so we'll look at the scalar tail.

constexpr wchar_t non_ascii_character{L'\u044F'}; // U+044F CYRILLIC SMALL LETTER YA, any value >= 256 works

{
const auto pos1{haystack.find_first_of(needle)};
assert(pos1 == wstring::npos);
}
{
haystack[146] = non_ascii_character;
const auto pos2{haystack.find_first_of(needle)};
assert(pos2 == wstring::npos);
haystack[146] = L'x';
}
{
haystack[148] = L'b';
const auto pos3{haystack.find_first_of(needle)};
assert(pos3 == 148);
haystack[148] = L'x';
}
{
haystack[146] = non_ascii_character;
haystack[148] = L'b';
const auto pos4{haystack.find_first_of(needle)};
assert(pos4 == 148);
haystack[146] = L'x';
haystack[148] = L'x';
}
}

void test_string(mt19937_64& gen) {
test_basic_string<char>(gen);
test_basic_string<wchar_t>(gen);
Expand All @@ -1884,6 +1922,7 @@ void test_string(mt19937_64& gen) {
test_basic_string<unsigned long long>(gen);

test_gh_5757_find_first_of();
test_gh_6342_find_first_of();
}

void test_various_containers() {
Expand Down