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
1 change: 1 addition & 0 deletions stl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_bit_utils.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_chrono.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_cxx_stdatomic.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_doom_core.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_filebuf.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_format_ucd_tables.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_formatter.hpp
Expand Down
54 changes: 54 additions & 0 deletions stl/inc/__msvc_doom_core.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// __msvc_doom_core.hpp internal header (core)

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef __MSVC_DOOM_CORE_HPP
#define __MSVC_DOOM_CORE_HPP
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR

#ifdef _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION
#include <cstdlib>
#elif defined(_M_CEE)
#include <corecrt.h>
#endif // ^^^ defined(_M_CEE) ^^^

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

// The STL's "doom function" can be replaced. Notes:
// * It must not throw. (Attempting to throw would slam into noexcept.)
// * Common case: If it doesn't return, it should be marked as `[[noreturn]]`.
// * Uncommon case: If it returns, the STL will attempt to "continue on error", behaving as if no checking was done.
// + For example, a legacy codebase with a long startup time might want to log errors for investigation later.
// + WARNING: If you replace the STL's "doom function" to "continue on error", you do so at your own risk!
// After the STL has detected a precondition violation, undefined behavior is imminent. The STL will support
// "continue on error" by proceeding to do what it would have done anyways (instead of falling off the end of
// a non-void function, etc.), but it will not attempt to replace undefined behavior with implementation-defined
// behavior. (For example, we will not transform `pop_back()` of an empty `vector` to be a no-op.)
#ifndef _MSVC_STL_DOOM_FUNCTION
#ifdef _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION // The user wants to use abort():
#define _MSVC_STL_DOOM_FUNCTION(mesg) _CSTD abort()
#elif defined(__clang__) // Use the Clang intrinsic:
#define _MSVC_STL_DOOM_FUNCTION(mesg) __builtin_verbose_trap("MSVC STL error", mesg)
#elif defined(_M_CEE) // TRANSITION, VSO-2457624 (/clr silent bad codegen for __fastfail); /clr:pure lacks __fastfail
#define _MSVC_STL_DOOM_FUNCTION(mesg) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0)
#else // Use the MSVC __fastfail intrinsic:
extern "C" __declspec(noreturn) void __fastfail(unsigned int); // declared by <intrin.h>
#define _MSVC_STL_DOOM_FUNCTION(mesg) \
__fastfail(5); /* __fastfail(FAST_FAIL_INVALID_ARG), value defined by <winnt.h> */ \
_STL_UNREACHABLE /* TRANSITION, DevCom-10914110 */
#endif // choose "doom function"
#endif // ^^^ !defined(_MSVC_STL_DOOM_FUNCTION) ^^^

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // __MSVC_DOOM_CORE_HPP
1 change: 1 addition & 0 deletions stl/inc/header-units.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"__msvc_bit_utils.hpp",
"__msvc_chrono.hpp",
"__msvc_cxx_stdatomic.hpp",
"__msvc_doom_core.hpp",
"__msvc_filebuf.hpp",
"__msvc_format_ucd_tables.hpp",
"__msvc_formatter.hpp",
Expand Down
4 changes: 4 additions & 0 deletions stl/inc/utility
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define _UTILITY_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <__msvc_doom_core.hpp>
#include <initializer_list>
#include <type_traits>

Expand Down Expand Up @@ -1013,6 +1014,9 @@ _NODISCARD constexpr underlying_type_t<_Ty> to_underlying(_Ty _Value) noexcept {
}

_EXPORT_STD [[noreturn]] __forceinline void unreachable() noexcept /* strengthened */ {
#ifdef _DEBUG
_MSVC_STL_DOOM_FUNCTION("std::unreachable() called");
#endif // defined(_DEBUG)
_STL_UNREACHABLE;
}

Expand Down
26 changes: 1 addition & 25 deletions stl/inc/yvals.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ _EMIT_STL_ERROR(
STL1005, "Tried to include a non-core C++ Standard Library header file with _ENFORCE_ONLY_CORE_HEADERS defined.");
#endif // defined(_ENFORCE_ONLY_CORE_HEADERS)

#include <__msvc_doom_core.hpp>
#include <crtdbg.h>
#include <crtdefs.h>

Expand Down Expand Up @@ -248,31 +249,6 @@ _EMIT_STL_ERROR(STL1008, "_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER has been
"It was superseded by _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION.");
#endif

// The STL's "doom function" can be replaced. Notes:
// * It must not throw. (Attempting to throw would slam into noexcept.)
// * Common case: If it doesn't return, it should be marked as `[[noreturn]]`.
// * Uncommon case: If it returns, the STL will attempt to "continue on error", behaving as if no checking was done.
// + For example, a legacy codebase with a long startup time might want to log errors for investigation later.
// + WARNING: If you replace the STL's "doom function" to "continue on error", you do so at your own risk!
// After the STL has detected a precondition violation, undefined behavior is imminent. The STL will support
// "continue on error" by proceeding to do what it would have done anyways (instead of falling off the end of
// a non-void function, etc.), but it will not attempt to replace undefined behavior with implementation-defined
// behavior. (For example, we will not transform `pop_back()` of an empty `vector` to be a no-op.)
#ifndef _MSVC_STL_DOOM_FUNCTION
#ifdef _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION // The user wants to use abort():
#define _MSVC_STL_DOOM_FUNCTION(mesg) _CSTD abort()
#elif defined(__clang__) // Use the Clang intrinsic:
#define _MSVC_STL_DOOM_FUNCTION(mesg) __builtin_verbose_trap("MSVC STL error", mesg)
#elif defined(_M_CEE) // TRANSITION, VSO-2457624 (/clr silent bad codegen for __fastfail); /clr:pure lacks __fastfail
#define _MSVC_STL_DOOM_FUNCTION(mesg) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0)
#else // Use the MSVC __fastfail intrinsic:
extern "C" __declspec(noreturn) void __fastfail(unsigned int); // declared by <intrin.h>
#define _MSVC_STL_DOOM_FUNCTION(mesg) \
__fastfail(5); /* __fastfail(FAST_FAIL_INVALID_ARG), value defined by <winnt.h> */ \
_STL_UNREACHABLE /* TRANSITION, DevCom-10914110 */
#endif // choose "doom function"
#endif // ^^^ !defined(_MSVC_STL_DOOM_FUNCTION) ^^^

#define _STL_REPORT_ERROR(mesg) \
_RPTF0(_CRT_ASSERT, mesg); \
_MSVC_STL_DOOM_FUNCTION(mesg)
Expand Down
2 changes: 2 additions & 0 deletions tests/std/tests/GH_001411_core_headers/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

// Also test GH-3103 "<xatomic.h>: Investigate making this a core header" and other internal core headers
#include <__msvc_int128.hpp>
#include <__msvc_minmax.hpp>
Comment thread
StephanTLavavej marked this conversation as resolved.
#include <__msvc_system_error_abi.hpp>
#include <__msvc_threads_core.hpp>
#include <__msvc_xlocinfo_types.hpp>
Expand All @@ -25,6 +26,7 @@
#endif // ^^^ _HAS_CXX20 ^^^

// <__msvc_bit_utils.hpp> is included by <bit> and <limits>
// <__msvc_doom_core.hpp> is included by <utility>
Comment thread
StephanTLavavej marked this conversation as resolved.
// <__msvc_iter_core.hpp> is included by <tuple>
// <xkeycheck.h> should not be included outside of <yvals_core.h>
// <xtr1common> is included by <cstddef>
Expand Down
3 changes: 3 additions & 0 deletions tests/std/tests/P0627R6_unreachable/env.lst
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
RUNALL_CROSSLIST
* PM_CL=""
* PM_CL="/D_MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION"
11 changes: 5 additions & 6 deletions tests/std/tests/P0627R6_unreachable/test.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <utility>
#include <utility> // Only include <utility> to test compilation of doom function without additional includes.

constexpr char test_impl(const int arg) {
switch (arg) {
Expand All @@ -18,13 +17,13 @@ constexpr char test_impl(const int arg) {
}

constexpr bool test() {
assert(test_impl(1) == 'a');
assert(test_impl(2) == 'z');
return true;
return test_impl(1) == 'a' && test_impl(2) == 'z';
}

int main() {
test();
if (!test()) {
return 1;
}
static_assert(test());
static_assert(noexcept(std::unreachable())); // strengthened
}