diff --git a/stl/inc/locale b/stl/inc/locale index cc08f4d4ee..d493db8278 100644 --- a/stl/inc/locale +++ b/stl/inc/locale @@ -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(_Hash_array_representation(_First, static_cast(_Last - _First))); + const auto _Sortkey = collate::do_transform(_First, _Last); + return static_cast(_Hash_array_representation(_Sortkey.data(), _Sortkey.size())); } private: diff --git a/tests/std/tests/GH_005236_collate_facet/test.cpp b/tests/std/tests/GH_005236_collate_facet/test.cpp index 4938f5cc1a..bd9ea184af 100644 --- a/tests/std/tests/GH_005236_collate_facet/test.cpp +++ b/tests/std/tests/GH_005236_collate_facet/test.cpp @@ -96,6 +96,24 @@ void test_gh_5210() { #endif // !defined(SKIP_COLLATE_TRANSFORM_TESTS) } +void test_gh_5212_compare_hash(const collate& 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>(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 +} + // GH-5236 "std::collate 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 @@ -117,5 +135,6 @@ void test_gh_5236() { int main() { test_gh_5210(); + test_gh_5212(); test_gh_5236(); }