diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 5a70bb2cb4..fb5d03cce7 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -144,7 +144,7 @@ public: _Atomic_counter_t _Myrefs; // the reference count protected: - explicit __CLR_OR_THIS_CALL facet(size_t _Initrefs = 0) + explicit __CLR_OR_THIS_CALL facet(size_t _Initrefs = 0) noexcept // strengthened : _Myrefs(static_cast<_Atomic_counter_t>(_Initrefs)) // non-atomic initialization {} @@ -618,7 +618,9 @@ inline unsigned short* __CRTDECL _Maklocstr(const char* _Ptr, unsigned short*, c } #endif // defined(_NATIVE_WCHAR_T_DEFINED) && !_ENFORCE_FACET_SPECIALIZATIONS -_EXPORT_STD extern "C++" class _CRTIMP2_PURE_IMPORT codecvt_base : public locale::facet { // base class for codecvt +_EXPORT_STD extern "C++" class _CRTIMP2_PURE_IMPORT codecvt_base // base class for codecvt + : public locale::facet // TRANSITION, ABI, shouldn't be derived from locale::facet +{ public: enum { // constants for different parse states ok, @@ -628,7 +630,8 @@ public: }; using result = int; - __CLR_OR_THIS_CALL codecvt_base(size_t _Refs = 0) : locale::facet(_Refs) {} + __CLR_OR_THIS_CALL codecvt_base(size_t _Refs = 0) noexcept // strengthened + : locale::facet(_Refs) {} bool __CLR_OR_THIS_CALL always_noconv() const noexcept { // return true if conversions never change input (from codecvt) @@ -2361,7 +2364,9 @@ protected: #define _UP _UPPER // 'A'-'Z' #define _XD _HEX // '0'-'9', 'A'-'F', 'a'-'f' -_EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT ctype_base : locale::facet { // base for ctype +_EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT ctype_base // base for ctype + : locale::facet // TRANSITION, ABI, shouldn't be derived from locale::facet +{ enum { // constants for character classifications alnum = _DI | _LO | _UP | _XA, alpha = _LO | _UP | _XA, @@ -2378,7 +2383,8 @@ _EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT ctype_base : locale::facet }; using mask = short; // to match - __CLR_OR_THIS_CALL ctype_base(size_t _Refs = 0) : locale::facet(_Refs) {} + __CLR_OR_THIS_CALL ctype_base(size_t _Refs = 0) noexcept // strengthened + : locale::facet(_Refs) {} __CLR_OR_THIS_CALL ~ctype_base() noexcept override {} }; diff --git a/stl/inc/xlocmes b/stl/inc/xlocmes index 171bea273f..ca9355f1d9 100644 --- a/stl/inc/xlocmes +++ b/stl/inc/xlocmes @@ -18,10 +18,14 @@ _STL_DISABLE_CLANG_WARNINGS #undef new _STD_BEGIN -_EXPORT_STD struct messages_base : locale::facet { // base class for messages +_EXPORT_STD struct messages_base // base class for messages + : locale::facet // TRANSITION, ABI, shouldn't be derived from locale::facet +{ using catalog = int; - explicit messages_base(size_t _Refs = 0) : locale::facet(_Refs) {} + messages_base() noexcept // strengthened + : messages_base(0) {} + explicit messages_base(size_t _Refs) noexcept : locale::facet(_Refs) {} }; _EXPORT_STD template diff --git a/stl/inc/xlocmon b/stl/inc/xlocmon index a8c1eafabd..7fb534b852 100644 --- a/stl/inc/xlocmon +++ b/stl/inc/xlocmon @@ -19,7 +19,9 @@ _STL_DISABLE_CLANG_WARNINGS #undef new _STD_BEGIN -_EXPORT_STD struct money_base : locale::facet { // ultimate base class for moneypunct +_EXPORT_STD struct money_base // ultimate base class for moneypunct + : locale::facet // TRANSITION, ABI, shouldn't be derived from locale::facet +{ enum { // constants for different format codes symbol = '$', sign = '+', @@ -33,7 +35,8 @@ _EXPORT_STD struct money_base : locale::facet { // ultimate base class for money char field[4]; }; - money_base(size_t _Refs = 0) : locale::facet(_Refs) {} + money_base(size_t _Refs = 0) noexcept // strengthened + : locale::facet(_Refs) {} }; template diff --git a/stl/inc/xloctime b/stl/inc/xloctime index 722feeb330..8b30b8493e 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -86,7 +86,9 @@ ios_base::iostate _Getint_v2(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& return _State; } -_EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT time_base : locale::facet { // base class for time_get +_EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT time_base // base class for time_get + : locale::facet // TRANSITION, ABI, shouldn't be derived from locale::facet +{ enum dateorder { // constants for different orders of date components no_order, dmy, @@ -95,7 +97,8 @@ _EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT time_base : locale::facet { ydm }; - __CLR_OR_THIS_CALL time_base(size_t _Refs = 0) : locale::facet(_Refs) {} + __CLR_OR_THIS_CALL time_base(size_t _Refs = 0) noexcept // strengthened + : locale::facet(_Refs) {} __CLR_OR_THIS_CALL ~time_base() noexcept override {} }; diff --git a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp index 7a7cd8f9bf..af6eacb8aa 100644 --- a/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp +++ b/tests/std/tests/Dev09_056375_locale_cleanup/test.cpp @@ -14,6 +14,33 @@ using namespace std; STATIC_ASSERT(noexcept(locale{} == locale{})); STATIC_ASSERT(noexcept(locale{} != locale{})); +STATIC_ASSERT(is_nothrow_default_constructible_v); // strengthened +STATIC_ASSERT(is_nothrow_default_constructible_v); // strengthened +STATIC_ASSERT(is_nothrow_default_constructible_v); // strengthened +STATIC_ASSERT(is_nothrow_default_constructible_v); // strengthened +STATIC_ASSERT(is_nothrow_default_constructible_v); // strengthened + +// Test that *_base classes are implicitly default constructible. + +template +void parameter_taker(const T&); // not defined + +template +constexpr bool is_implicitly_default_constructible = false; + +template +constexpr bool is_implicitly_default_constructible({}))>> = true; + +STATIC_ASSERT(is_implicitly_default_constructible); +STATIC_ASSERT(is_implicitly_default_constructible); +STATIC_ASSERT(is_implicitly_default_constructible); +STATIC_ASSERT(is_implicitly_default_constructible); +STATIC_ASSERT(is_implicitly_default_constructible); + +STATIC_ASSERT(!is_implicitly_default_constructible); +STATIC_ASSERT(!is_implicitly_default_constructible>); +STATIC_ASSERT(!is_implicitly_default_constructible>); + void test_dll() { puts("Calling dll"); #ifdef _M_CEE