Skip to content

Commit

Permalink
Strengthen exception specification for some facet base types (#3855)
Browse files Browse the repository at this point in the history
  • Loading branch information
frederick-vs-ja authored Jul 14, 2023
1 parent 750ec42 commit 828fa10
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 11 deletions.
16 changes: 11 additions & 5 deletions stl/inc/xlocale
Original file line number Diff line number Diff line change
Expand Up @@ -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
{}

Expand Down Expand Up @@ -620,7 +620,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,
Expand All @@ -630,7 +632,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)
Expand Down Expand Up @@ -2363,7 +2366,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,
Expand All @@ -2380,7 +2385,8 @@ _EXPORT_STD extern "C++" struct _CRTIMP2_PURE_IMPORT ctype_base : locale::facet
};
using mask = short; // to match <ctype.h>

__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 {}
};
Expand Down
8 changes: 6 additions & 2 deletions stl/inc/xlocmes
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class _Elem>
Expand Down
7 changes: 5 additions & 2 deletions stl/inc/xlocmon
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '+',
Expand All @@ -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 <class _Elem>
Expand Down
7 changes: 5 additions & 2 deletions stl/inc/xloctime
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {}
};
Expand Down
27 changes: 27 additions & 0 deletions tests/std/tests/Dev09_056375_locale_cleanup/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,33 @@ using namespace std;
STATIC_ASSERT(noexcept(locale{} == locale{})); // strengthened
STATIC_ASSERT(noexcept(locale{} != locale{})); // strengthened

STATIC_ASSERT(is_nothrow_default_constructible_v<ctype_base>); // strengthened
STATIC_ASSERT(is_nothrow_default_constructible_v<codecvt_base>); // strengthened
STATIC_ASSERT(is_nothrow_default_constructible_v<time_base>); // strengthened
STATIC_ASSERT(is_nothrow_default_constructible_v<money_base>); // strengthened
STATIC_ASSERT(is_nothrow_default_constructible_v<messages_base>); // strengthened

// Test that *_base classes are implicitly default constructible.

template <class T>
void parameter_taker(const T&); // not defined

template <class T, class = void>
constexpr bool is_implicitly_default_constructible = false;

template <class T>
constexpr bool is_implicitly_default_constructible<T, void_t<decltype(parameter_taker<T>({}))>> = true;

STATIC_ASSERT(is_implicitly_default_constructible<ctype_base>);
STATIC_ASSERT(is_implicitly_default_constructible<codecvt_base>);
STATIC_ASSERT(is_implicitly_default_constructible<time_base>);
STATIC_ASSERT(is_implicitly_default_constructible<money_base>);
STATIC_ASSERT(is_implicitly_default_constructible<messages_base>);

STATIC_ASSERT(!is_implicitly_default_constructible<locale::facet>);
STATIC_ASSERT(!is_implicitly_default_constructible<ctype<char>>);
STATIC_ASSERT(!is_implicitly_default_constructible<ctype<wchar_t>>);

void test_dll() {
puts("Calling dll");
#ifdef _M_CEE
Expand Down

0 comments on commit 828fa10

Please sign in to comment.