From 7337bbb020ec6a9d2660fbe63b285f8801cf6c3a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Jun 2023 13:44:26 +0800 Subject: [PATCH 1/3] Test coverage and precondition checking for LWG-2295 --- stl/inc/xlocale | 2 + .../Dev09_056375_locale_cleanup/test.cpp | 126 +++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 5a70bb2cb4..c2b2decbad 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -280,6 +280,7 @@ public: locale(const locale& _Loc, const locale& _Other, category _Cat) : _Ptr(_Locimp::_New_Locimp(*_Loc._Ptr)) { // construct a locale by copying named facets if (_Cat != none) { // worth adding, do it + _STL_ASSERT((_Cat & all) == _Cat, "the bitmask value specifying category must be valid"); _Facet_guard _Guard{_Ptr}; _BEGIN_LOCINFO(_Lobj) _Locimp::_Makeloc(_Lobj, _Cat, _Ptr, &_Other); @@ -294,6 +295,7 @@ public: private: void _Construct(const string& _Str, category _Cat) { + _STL_ASSERT((_Cat & all) == _Cat, "the bitmask value specifying category must be valid"); // construct a locale with named facets bool _Bad = false; _Init(); diff --git a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp index 7a7cd8f9bf..38b04239cb 100644 --- a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp +++ b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING + #include #include #include @@ -11,8 +13,8 @@ using namespace std; #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -STATIC_ASSERT(noexcept(locale{} == locale{})); -STATIC_ASSERT(noexcept(locale{} != locale{})); +STATIC_ASSERT(noexcept(locale{} == locale{})); // strengthened +STATIC_ASSERT(noexcept(locale{} != locale{})); // strengthened void test_dll() { puts("Calling dll"); @@ -50,8 +52,128 @@ void test_exe_part2() { assert(!isspace(L'Z', locale())); } + +locale make_unnamed_locale() { + locale result{locale{"C"}, &use_facet>(locale{"C"})}; + assert(result.name() == "*"); + return result; +} + +template +void test_locale_name_with_facet_pointer_one() { + { + locale result{locale{"C"}, static_cast(nullptr)}; + assert(result.name() == "C"); + } + { + locale result{make_unnamed_locale(), static_cast(nullptr)}; + assert(result.name() == "*"); + } + { + locale le{"C"}; + locale result{le, &use_facet(le)}; + assert(result.name() == "*"); + } + { + locale lunnamed{make_unnamed_locale()}; + locale result{lunnamed, &use_facet(lunnamed)}; + assert(result.name() == "*"); + } +} + +void test_locale_name_with_facet_pointer_all() { + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); +#ifdef __cpp_char8_t + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); +#endif // __cpp_char8_t + test_locale_name_with_facet_pointer_one>(); + + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); + + test_locale_name_with_facet_pointer_one>(); + test_locale_name_with_facet_pointer_one>(); +} + +void test_locale_name_with_another_locale_and_cats() { + locale lc{"C"}; + locale lunnamed{make_unnamed_locale()}; + { + std::locale result{lc, lc, std::locale::none}; + assert(result.name() != "*"); + } + { + std::locale result{lc, lunnamed, std::locale::none}; + assert(result.name() != "*"); + } + { + std::locale result{lunnamed, lc, std::locale::none}; + assert(result.name() == "*"); + } + { + std::locale result{lunnamed, lunnamed, std::locale::none}; + assert(result.name() == "*"); + } + + constexpr int cats_masks_count = 6; // collate | ctype | monetary | numeric | time | messages + for (int precats = 1; precats < (1 << cats_masks_count); ++precats) { + const locale::category cats = ((precats & (1 << 0)) != 0 ? locale::collate : locale::none) + | ((precats & (1 << 1)) != 0 ? locale::ctype : locale::none) + | ((precats & (1 << 2)) != 0 ? locale::monetary : locale::none) + | ((precats & (1 << 3)) != 0 ? locale::numeric : locale::none) + | ((precats & (1 << 4)) != 0 ? locale::time : locale::none) + | ((precats & (1 << 5)) != 0 ? locale::messages : locale::none); + { + std::locale result{lc, lc, cats}; + assert(result.name() != "*"); + } + { + std::locale result{lc, lunnamed, cats}; + assert(result.name() == "*"); + } + { + std::locale result{lunnamed, lc, cats}; + assert(result.name() == "*"); + } + { + std::locale result{lunnamed, lunnamed, cats}; + assert(result.name() == "*"); + } + } +} + int main() { test_exe_part1(); test_dll(); test_exe_part2(); + + // test coverage for LWG-2295 + test_locale_name_with_facet_pointer_all(); + test_locale_name_with_another_locale_and_cats(); } From b4ccb0925a0cfeced9fe4007d4eafb20f798cbc5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 3 Jul 2023 14:02:41 -0700 Subject: [PATCH 2/3] Drop std qualification. --- .../tests/Dev09_056375_locale_cleanup/test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp index 38b04239cb..3de94513ef 100644 --- a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp +++ b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp @@ -125,19 +125,19 @@ void test_locale_name_with_another_locale_and_cats() { locale lc{"C"}; locale lunnamed{make_unnamed_locale()}; { - std::locale result{lc, lc, std::locale::none}; + locale result{lc, lc, locale::none}; assert(result.name() != "*"); } { - std::locale result{lc, lunnamed, std::locale::none}; + locale result{lc, lunnamed, locale::none}; assert(result.name() != "*"); } { - std::locale result{lunnamed, lc, std::locale::none}; + locale result{lunnamed, lc, locale::none}; assert(result.name() == "*"); } { - std::locale result{lunnamed, lunnamed, std::locale::none}; + locale result{lunnamed, lunnamed, locale::none}; assert(result.name() == "*"); } @@ -150,19 +150,19 @@ void test_locale_name_with_another_locale_and_cats() { | ((precats & (1 << 4)) != 0 ? locale::time : locale::none) | ((precats & (1 << 5)) != 0 ? locale::messages : locale::none); { - std::locale result{lc, lc, cats}; + locale result{lc, lc, cats}; assert(result.name() != "*"); } { - std::locale result{lc, lunnamed, cats}; + locale result{lc, lunnamed, cats}; assert(result.name() == "*"); } { - std::locale result{lunnamed, lc, cats}; + locale result{lunnamed, lc, cats}; assert(result.name() == "*"); } { - std::locale result{lunnamed, lunnamed, cats}; + locale result{lunnamed, lunnamed, cats}; assert(result.name() == "*"); } } From 47c04d69148c319e731c44b8f20441e29c58b6e1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 13 Jul 2023 12:13:56 -0700 Subject: [PATCH 3/3] Avoid `/clr:pure` linker errors. --- tests/std/tests/Dev09_056375_locale_cleanup/test.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp index 3de94513ef..5f3c899806 100644 --- a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp +++ b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp @@ -52,7 +52,7 @@ void test_exe_part2() { assert(!isspace(L'Z', locale())); } - +#ifndef _M_CEE_PURE locale make_unnamed_locale() { locale result{locale{"C"}, &use_facet>(locale{"C"})}; assert(result.name() == "*"); @@ -167,13 +167,16 @@ void test_locale_name_with_another_locale_and_cats() { } } } +#endif // _M_CEE_PURE int main() { test_exe_part1(); test_dll(); test_exe_part2(); +#ifndef _M_CEE_PURE // test coverage for LWG-2295 test_locale_name_with_facet_pointer_all(); test_locale_name_with_another_locale_and_cats(); +#endif // _M_CEE_PURE }