Merge pull request #851 from JordanMaples/dev/jomaples/exception

prevent exception include when in no-exception mode.
This commit is contained in:
Jordan Maples [MSFT] 2020-03-17 13:41:33 -07:00 committed by GitHub
commit d90fefea6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -17,8 +17,27 @@
#ifndef GSL_CONTRACTS_H #ifndef GSL_CONTRACTS_H
#define GSL_CONTRACTS_H #define GSL_CONTRACTS_H
//
// Temporary until MSVC STL supports no-exceptions mode.
// Currently terminate is a no-op in this mode, so we add termination behavior back
//
#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#endif // defined(__clang__)
#else // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
#include <exception> #include <exception>
#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
// //
// make suppress attributes parse for some compilers // make suppress attributes parse for some compilers
// Hopefully temporary until suppression standardization occurs // Hopefully temporary until suppression standardization occurs
@ -33,32 +52,18 @@
#endif // _MSC_VER #endif // _MSC_VER
#endif // __clang__ #endif // __clang__
//
// Temporary until MSVC STL supports no-exceptions mode.
// Currently terminate is a no-op in this mode, so we add termination behavior back
//
#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#endif
#endif
#define GSL_STRINGIFY_DETAIL(x) #x #define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) #define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1) #define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0) #define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else #else
#define GSL_LIKELY(x) (!!(x)) #define GSL_LIKELY(x) (!!(x))
#define GSL_UNLIKELY(x) (!!(x)) #define GSL_UNLIKELY(x) (!!(x))
#endif #endif // defined(__clang__) || defined(__GNUC__)
// //
// GSL_ASSUME(cond) // GSL_ASSUME(cond)
@ -85,9 +90,11 @@ namespace details
{ {
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) #if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
typedef void (__cdecl *terminate_handler)(); typedef void(__cdecl* terminate_handler)();
// clang-format off
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
// clang-format on
[[noreturn]] inline void __cdecl default_terminate_handler() [[noreturn]] inline void __cdecl default_terminate_handler()
{ {
__fastfail(RANGE_CHECKS_FAILURE); __fastfail(RANGE_CHECKS_FAILURE);
@ -99,7 +106,7 @@ namespace details
return handler; return handler;
} }
#endif #endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
[[noreturn]] inline void terminate() noexcept [[noreturn]] inline void terminate() noexcept
{ {
@ -107,21 +114,12 @@ namespace details
(*gsl::details::get_terminate_handler())(); (*gsl::details::get_terminate_handler())();
#else #else
std::terminate(); std::terminate();
#endif #endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
} }
template <typename Exception>
[[deprecated("GSL no longer supports throwing for contract violations. Use gsl::details::terminate() instead.")]]
[[noreturn]] void throw_exception(Exception&&) noexcept
{
gsl::details::terminate();
}
} // namespace details } // namespace details
} // namespace gsl } // namespace gsl
#define GSL_CONTRACT_CHECK(type, cond) \ #define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate()) (GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())