Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions stl/inc/system_error
Original file line number Diff line number Diff line change
Expand Up @@ -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, <system_error> would be a huge regression vs. legacy error codes).
Expand Down Expand Up @@ -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 <class _Ty>
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 <class _Ty>
_NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept {
static _Constexpr_immortalize_impl<_Ty> _Static;
return _Static._Storage;
}
#else // choose immortalize strategy
template <class _Ty>
_NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept {
Expand Down
28 changes: 26 additions & 2 deletions stl/src/excptptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class _Ty>
_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 <class _Ty>
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 <class _Ty>
_Constexpr_excptptr_immortalize_impl<_Ty> _Immortalize_impl;

template <class _Ty>
_NODISCARD _Ty& _Immortalize() noexcept {
return _Immortalize_impl<_Ty>._Storage;
}
#else // choose immortalize strategy
template <class _Ty>
int __stdcall _Immortalize_impl(void*, void* _Storage_ptr, void**) noexcept {
// adapt True Placement New to _Execute_once
Expand Down