Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions stl/inc/locale
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ protected:

_NODISCARD virtual long __CLR_OR_THIS_CALL do_hash(const _Elem* _First, const _Elem* _Last) const {
// compute hash code for [_First, _Last)
_Adl_verify_range(_First, _Last);
return static_cast<long>(_Hash_array_representation(_First, static_cast<size_t>(_Last - _First)));
const auto _Sortkey = collate::do_transform(_First, _Last);
return static_cast<long>(_Hash_array_representation(_Sortkey.data(), _Sortkey.size()));
}

private:
Expand Down
24 changes: 24 additions & 0 deletions tests/std/tests/GH_005236_collate_facet/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,29 @@ void test_gh_5210() {
#endif // !defined(SKIP_COLLATE_TRANSFORM_TESTS)
}

// GH-5469 fixed this by making collate::do_hash() call collate::do_transform()
#ifdef SKIP_COLLATE_TRANSFORM_TESTS
void test_gh_5212() {}
#else // ^^^ defined(SKIP_COLLATE_TRANSFORM_TESTS) / !defined(SKIP_COLLATE_TRANSFORM_TESTS) vvv
void test_gh_5212_compare_hash(const collate<wchar_t>& coll, const wstring& string1, const wstring& string2) {
assert(coll.hash(string1.data(), string1.data() + string1.size())
== coll.hash(string2.data(), string2.data() + string2.size()));
}

// GH-5212: std::collate_byname<_Elem>::hash() yields different hashes for strings that collate the same
void test_gh_5212() {
const locale loc("de-DE_phoneb");
const auto& coll = use_facet<collate<wchar_t>>(loc);

// sharp s collates like "ss"
test_gh_5212_compare_hash(coll, L"Strasse", L"Stra\u00DFe"); // U+00DF LATIN SMALL LETTER SHARP S
// umlaut a collates like "ae"
test_gh_5212_compare_hash(coll, L"Kaetzchen", L"K\u00E4tzchen"); // U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
// umlaut A collates like "AE"
test_gh_5212_compare_hash(coll, L"AErmel", L"\u00C4rmel"); // U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
}
#endif // ^^^ !defined(SKIP_COLLATE_TRANSFORM_TESTS) ^^^

// GH-5236 "std::collate<wchar_t> does not respect collation order when compiled with /MD(d) /Zc:wchar_t-"
void test_gh_5236() {
const wchar_t Ue = L'\u00DC'; // U+00DC LATIN CAPITAL LETTER U WITH DIARESIS
Expand All @@ -117,5 +140,6 @@ void test_gh_5236() {

int main() {
test_gh_5210();
test_gh_5212();
test_gh_5236();
}