diff --git a/stl/inc/system_error b/stl/inc/system_error index 4121c5766d9..bb73811a85c 100644 --- a/stl/inc/system_error +++ b/stl/inc/system_error @@ -513,8 +513,7 @@ public: } }; -// -// TRANSITION, VSO-1043450 +// TRANSITION, Visual Studio 2019 version 16.8 // _Immortalize_memcpy_image is used to provide a nonstandard guarantee. // Specifically, we want the error category objects returned from things like std::system_category() to always // be available, even during DLL unload (otherwise, would be a huge regression vs. legacy error codes). @@ -557,6 +556,28 @@ _NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept { static constexpr _Ty _Static; return _Static; } +#elif defined(_MSC_VER) && _MSC_VER > 1927 && !defined(_M_CEE) // _M_CEE test is TRANSITION, VSO-1153256 +template +struct _Constexpr_immortalize_impl { + union { + _Ty _Storage; + }; + + constexpr _Constexpr_immortalize_impl() noexcept : _Storage{} {} + + _Constexpr_immortalize_impl(const _Constexpr_immortalize_impl&) = delete; + _Constexpr_immortalize_impl& operator=(const _Constexpr_immortalize_impl&) = delete; + + [[msvc::noop_dtor]] ~_Constexpr_immortalize_impl() { + // do nothing, allowing _Ty to be used during shutdown + } +}; + +template +_NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept { + static _Constexpr_immortalize_impl<_Ty> _Static; + return _Static._Storage; +} #else // choose immortalize strategy template _NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept { diff --git a/stl/src/excptptr.cpp b/stl/src/excptptr.cpp index 821697998c6..b0e85953014 100644 --- a/stl/src/excptptr.cpp +++ b/stl/src/excptptr.cpp @@ -37,13 +37,37 @@ extern "C" _CRTIMP2 void* __cdecl __AdjustPointer(void*, const PMD&); // defined using namespace std; namespace { -#ifdef _M_CEE_PURE +#if defined(_M_CEE_PURE) template _Ty& _Immortalize() { // return a reference to an object that will live forever /* MAGIC */ static _Immortalizer_impl<_Ty> _Static; return reinterpret_cast<_Ty&>(_Static._Storage); } -#else // ^^^ _M_CEE_PURE ^^^ // vvv !_M_CEE_PURE vvv +#elif _MSC_VER > 1927 && !defined(_M_CEE) // _M_CEE test is TRANSITION, VSO-1153256 + template + struct _Constexpr_excptptr_immortalize_impl { + union { + _Ty _Storage; + }; + + constexpr _Constexpr_excptptr_immortalize_impl() noexcept : _Storage{} {} + + _Constexpr_excptptr_immortalize_impl(const _Constexpr_excptptr_immortalize_impl&) = delete; + _Constexpr_excptptr_immortalize_impl& operator=(const _Constexpr_excptptr_immortalize_impl&) = delete; + + [[msvc::noop_dtor]] ~_Constexpr_excptptr_immortalize_impl() { + // do nothing, allowing _Ty to be used during shutdown + } + }; + + template + _Constexpr_excptptr_immortalize_impl<_Ty> _Immortalize_impl; + + template + _NODISCARD _Ty& _Immortalize() noexcept { + return _Immortalize_impl<_Ty>._Storage; + } +#else // choose immortalize strategy template int __stdcall _Immortalize_impl(void*, void* _Storage_ptr, void**) noexcept { // adapt True Placement New to _Execute_once