From 05fc45fd80014df245fdaade5321bb6d8c4f2ab5 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 30 Mar 2024 20:41:11 +0800 Subject: [PATCH 1/4] Implement LWG-3767 --- stl/inc/xlocale | 4 ++-- stl/inc/yvals_core.h | 21 +++++++++++++++---- .../Dev09_056375_locale_cleanup/test.cpp | 1 + .../tests/VSO_0397980_codecvt_length/test.cpp | 1 + 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 6a2f168ab72..73fbbf55b15 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -1397,7 +1397,7 @@ struct _NODISCARD _Codecvt_guard { }; extern "C++" template <> -class codecvt : public codecvt_base { +class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt : public codecvt_base { // facet for converting between UTF-16 and UTF-8 sequences public: using intern_type = char16_t; @@ -1678,7 +1678,7 @@ protected: }; extern "C++" template <> -class codecvt : public codecvt_base { +class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt : public codecvt_base { // facet for converting between UTF-32 and UTF-8 sequences public: using intern_type = char32_t; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index e027e322a9c..c993cb44356 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1253,9 +1253,9 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect [[deprecated("warning STL4020: " \ "std::codecvt, std::codecvt, " \ "std::codecvt_byname, and std::codecvt_byname " \ - "are deprecated in C++20 and replaced by specializations with a second argument of type char8_t. " \ - "You can define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING " \ - "or _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to suppress this warning.")]] + "are deprecated in C++20. std::filesystem::path can be used for desired conversions. You can define " \ + "_SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING or _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to " \ + "suppress this warning.")]] #else // ^^^ warning enabled / warning disabled vvv #define _CXX20_DEPRECATE_CODECVT_FACETS #endif // ^^^ warning disabled ^^^ @@ -1514,7 +1514,20 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define _DEPRECATE_TR1_RANDOM #endif // ^^^ warning disabled ^^^ -// next warning number: STL4047 +#if _HAS_CXX20 && defined(__cpp_char8_t) && !defined(_SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING) \ + && !defined(_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS) +#define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS \ + [[deprecated( \ + "warning STL4047: std::codecvt, std::codecvt, " \ + "std::codecvt_byname, and " \ + "std::codecvt_byname are deprecated by LWG-3767. std::filesystem::path can be " \ + "used for desired conversions. You can define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING or " \ + "_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to suppress this warning.")]] +#else // ^^^ warning enabled / warning disabled vvv +#define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS +#endif // ^^^ warning disabled ^^^ + +// next warning number: STL4048 // next error number: STL1006 diff --git a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp index 1fecfd287e3..02bbe0388cf 100644 --- a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp +++ b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING +#define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING #include #include diff --git a/tests/std/tests/VSO_0397980_codecvt_length/test.cpp b/tests/std/tests/VSO_0397980_codecvt_length/test.cpp index 7558dc5f4ec..9bcad7435f1 100644 --- a/tests/std/tests/VSO_0397980_codecvt_length/test.cpp +++ b/tests/std/tests/VSO_0397980_codecvt_length/test.cpp @@ -3,6 +3,7 @@ #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING #define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING +#define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING #undef _ENFORCE_FACET_SPECIALIZATIONS #define _ENFORCE_FACET_SPECIALIZATIONS 0 From 7ece4da4f0367a2892483377f65a9155ac4ab6af Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 2 Apr 2024 06:03:51 -0700 Subject: [PATCH 2/4] Suggesting `std::filesystem::path` would be squirrelly. --- stl/inc/yvals_core.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index c993cb44356..678341f07e9 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1253,9 +1253,8 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect [[deprecated("warning STL4020: " \ "std::codecvt, std::codecvt, " \ "std::codecvt_byname, and std::codecvt_byname " \ - "are deprecated in C++20. std::filesystem::path can be used for desired conversions. You can define " \ - "_SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING or _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to " \ - "suppress this warning.")]] + "are deprecated in C++20. You can define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING " \ + "or _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to suppress this warning.")]] #else // ^^^ warning enabled / warning disabled vvv #define _CXX20_DEPRECATE_CODECVT_FACETS #endif // ^^^ warning disabled ^^^ @@ -1516,12 +1515,11 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #if _HAS_CXX20 && defined(__cpp_char8_t) && !defined(_SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING) \ && !defined(_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS) -#define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS \ - [[deprecated( \ - "warning STL4047: std::codecvt, std::codecvt, " \ - "std::codecvt_byname, and " \ - "std::codecvt_byname are deprecated by LWG-3767. std::filesystem::path can be " \ - "used for desired conversions. You can define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING or " \ +#define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS \ + [[deprecated( \ + "warning STL4047: std::codecvt, std::codecvt, " \ + "std::codecvt_byname, and std::codecvt_byname " \ + "are deprecated by LWG-3767. You can define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING or " \ "_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to suppress this warning.")]] #else // ^^^ warning enabled / warning disabled vvv #define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS From 900513a05f7d037236ba234cfcf47389a9550732 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 2 Apr 2024 06:18:13 -0700 Subject: [PATCH 3/4] Cleanup before replication: Drop pointless comments in `codecvt_byname`. --- stl/inc/xlocale | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 73fbbf55b15..cb93a22c662 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -2321,7 +2321,7 @@ private: #endif // defined(_NATIVE_WCHAR_T_DEFINED) && !_ENFORCE_FACET_SPECIALIZATIONS _EXPORT_STD template -class codecvt_byname : public codecvt<_Elem, _Byte, _Statype> { // codecvt for named locale +class codecvt_byname : public codecvt<_Elem, _Byte, _Statype> { public: static_assert(!_ENFORCE_FACET_SPECIALIZATIONS || _Is_any_of_v(_Locinfo(_Locname), _Refs) {} // construct for named locale + : codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Locname), _Refs) {} explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0) - : codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Str.c_str()), _Refs) {} // construct for named locale + : codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Str.c_str()), _Refs) {} protected: __CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {} From 405a58ed99d56c99f14e8919cc1858a88442bb86 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 2 Apr 2024 06:29:39 -0700 Subject: [PATCH 4/4] Properly deprecate `codecvt_byname` specializations. Shrink the primary template's `_ENFORCE_FACET_SPECIALIZATIONS` list because `codecvt_byname` and `codecvt_byname` are becoming (deprecated) explicit specializations. Note that `codecvt_byname` and `codecvt_byname` were simply missing. Add the old and new deprecated explicit specializations, the latter being guarded by `#ifdef __cpp_char8_t`. Note that (unlike the primary template) they can use the injected-class-name `codecvt` in their delegating constructors because it isn't dependent anymore. There didn't seem to be a simple way to centralize this repetition without adding too much complexity, so I just spammed it out. We need to `_STL_DISABLE_DEPRECATED_WARNING`/`_STL_RESTORE_DEPRECATED_WARNING` because the base classes are deprecated. --- stl/inc/xlocale | 69 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/stl/inc/xlocale b/stl/inc/xlocale index cb93a22c662..2d47e75cdce 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -2324,11 +2324,8 @@ _EXPORT_STD template class codecvt_byname : public codecvt<_Elem, _Byte, _Statype> { public: static_assert(!_ENFORCE_FACET_SPECIALIZATIONS - || _Is_any_of_v, codecvt_byname, -#endif // defined(__cpp_char8_t) - codecvt_byname, codecvt_byname>, + || _Is_any_of_v, + codecvt_byname>, _FACET_SPECIALIZATION_MESSAGE); explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0) @@ -2341,6 +2338,68 @@ protected: __CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {} }; +_STL_DISABLE_DEPRECATED_WARNING + +template <> +class _CXX20_DEPRECATE_CODECVT_FACETS codecvt_byname + : public codecvt { +public: + explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0) + : codecvt(_Locinfo(_Locname), _Refs) {} + + explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0) + : codecvt(_Locinfo(_Str.c_str()), _Refs) {} + +protected: + __CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {} +}; + +template <> +class _CXX20_DEPRECATE_CODECVT_FACETS codecvt_byname + : public codecvt { +public: + explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0) + : codecvt(_Locinfo(_Locname), _Refs) {} + + explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0) + : codecvt(_Locinfo(_Str.c_str()), _Refs) {} + +protected: + __CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {} +}; + +#ifdef __cpp_char8_t +template <> +class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt_byname + : public codecvt { +public: + explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0) + : codecvt(_Locinfo(_Locname), _Refs) {} + + explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0) + : codecvt(_Locinfo(_Str.c_str()), _Refs) {} + +protected: + __CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {} +}; + +template <> +class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt_byname + : public codecvt { +public: + explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0) + : codecvt(_Locinfo(_Locname), _Refs) {} + + explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0) + : codecvt(_Locinfo(_Str.c_str()), _Refs) {} + +protected: + __CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {} +}; +#endif // defined(__cpp_char8_t) + +_STL_RESTORE_DEPRECATED_WARNING + #define _XA 0x100 // extra alphabetic #define _BB _CONTROL // BEL, BS, etc. #define _CN _SPACE // CR, FF, HT, NL, VT