From 91b851bd29264cf7cc6e260ef9a5426157f33a14 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 23 Apr 2025 17:04:44 -0700 Subject: [PATCH 1/2] Improve STL Hardening codegen: Use MSVC `__fastfail` or Clang `__builtin_verbose_trap`. + MSVC [`__fastfail`](https://learn.microsoft.com/en-us/cpp/intrinsics/fastfail?view=msvc-170): "Support for the native fast fail mechanism began in Windows 8." + Clang [`__builtin_verbose_trap`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-verbose-trap) + I measured `v[idx]` on x64 with `/O2`, and this reduced codegen size from 56 bytes to 29 bytes. Clang codegen was similarly improved. + In ``, we need to avoid a Clang error: argument to `__builtin_verbose_trap` must be a pointer to a constant string --- stl/inc/ranges | 32 ++++++++++++++++++++------------ stl/inc/yvals.h | 14 +++++++++----- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index 383ac8a3ace..0033e663051 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1160,16 +1160,20 @@ namespace ranges { constexpr _Iterator& operator+=(difference_type _Off) noexcept /* strengthened */ { #if _ITERATOR_DEBUG_LEVEL != 0 - if constexpr (sizeof(difference_type) > sizeof(_Index_type)) { - _STL_VERIFY(static_cast<_Index_type>(_Off) == _Off, - _Off > 0 ? "cannot advance repeat_view iterator past end (integer overflow)" - : "cannot advance repeat_view iterator before begin (integer overflow)"); - } - if (_Off > 0) { + if constexpr (sizeof(difference_type) > sizeof(_Index_type)) { + _STL_VERIFY(static_cast<_Index_type>(_Off) == _Off, + "cannot advance repeat_view iterator past end (integer overflow)"); + } + _STL_VERIFY(_Current <= (numeric_limits<_Index_type>::max)() - static_cast<_Index_type>(_Off), "cannot advance repeat_view iterator past end (integer overflow)"); } else { + if constexpr (sizeof(difference_type) > sizeof(_Index_type)) { + _STL_VERIFY(static_cast<_Index_type>(_Off) == _Off, + "cannot advance repeat_view iterator before begin (integer overflow)"); + } + _STL_VERIFY(_Current >= (numeric_limits<_Index_type>::min)() - static_cast<_Index_type>(_Off), "cannot advance repeat_view iterator before begin (integer overflow)"); } @@ -1183,16 +1187,20 @@ namespace ranges { } constexpr _Iterator& operator-=(difference_type _Off) noexcept /* strengthened */ { #if _ITERATOR_DEBUG_LEVEL != 0 - if constexpr (sizeof(difference_type) > sizeof(_Index_type)) { - _STL_VERIFY(static_cast<_Index_type>(_Off) == _Off, - _Off < 0 ? "cannot advance repeat_view iterator past end (integer overflow)" - : "cannot advance repeat_view iterator before begin (integer overflow)"); - } - if (_Off < 0) { + if constexpr (sizeof(difference_type) > sizeof(_Index_type)) { + _STL_VERIFY(static_cast<_Index_type>(_Off) == _Off, + "cannot advance repeat_view iterator past end (integer overflow)"); + } + _STL_VERIFY(_Current <= (numeric_limits<_Index_type>::max)() + static_cast<_Index_type>(_Off), "cannot advance repeat_view iterator past end (integer overflow)"); } else { + if constexpr (sizeof(difference_type) > sizeof(_Index_type)) { + _STL_VERIFY(static_cast<_Index_type>(_Off) == _Off, + "cannot advance repeat_view iterator before begin (integer overflow)"); + } + _STL_VERIFY(_Current >= (numeric_limits<_Index_type>::min)() + static_cast<_Index_type>(_Off), "cannot advance repeat_view iterator before begin (integer overflow)"); } diff --git a/stl/inc/yvals.h b/stl/inc/yvals.h index c8cfa973615..3122d7a0895 100644 --- a/stl/inc/yvals.h +++ b/stl/inc/yvals.h @@ -242,12 +242,16 @@ _EMIT_STL_ERROR(STL1008, "_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER has been // 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 +#ifdef _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION // The user wants to use abort(): #define _MSVC_STL_DOOM_FUNCTION(mesg) _CSTD abort() -#else // ^^^ defined(_MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION) / !defined(_MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION) vvv -// TRANSITION, GH-4858: after dropping Win7 support, we can directly call __fastfail(FAST_FAIL_INVALID_ARG). +#elif defined(__clang__) // Use the Clang intrinsic: +#define _MSVC_STL_DOOM_FUNCTION(mesg) __builtin_verbose_trap("MSVC STL error", mesg) +#elif defined(_M_CEE_PURE) // Use the classic function because /clr:pure lacks the MSVC __fastfail intrinsic: #define _MSVC_STL_DOOM_FUNCTION(mesg) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0) -#endif // ^^^ !defined(_MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION) ^^^ +#else // Use the MSVC __fastfail intrinsic: +extern "C" __declspec(noreturn) void __fastfail(unsigned int); // declared by +#define _MSVC_STL_DOOM_FUNCTION(mesg) __fastfail(5) // __fastfail(FAST_FAIL_INVALID_ARG), value defined by +#endif // choose "doom function" #endif // ^^^ !defined(_MSVC_STL_DOOM_FUNCTION) ^^^ #define _STL_REPORT_ERROR(mesg) \ @@ -494,7 +498,7 @@ class _CRTIMP2_PURE_IMPORT _EmptyLockit { // empty lock class used for bin compa } \ } -#define _RAISE(x) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0) +#define _RAISE(x) _MSVC_STL_DOOM_FUNCTION("_RAISE was called with !_HAS_EXCEPTIONS") #define _RERAISE #define _THROW(...) (__VA_ARGS__)._Raise() From fddc65dac78d2f565da922e7f4a7009d6d563e13 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 25 Apr 2025 10:04:44 -0700 Subject: [PATCH 2/2] Work around /clr silent bad codegen. --- stl/inc/yvals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/yvals.h b/stl/inc/yvals.h index 3122d7a0895..f6c6d4a2288 100644 --- a/stl/inc/yvals.h +++ b/stl/inc/yvals.h @@ -246,7 +246,7 @@ _EMIT_STL_ERROR(STL1008, "_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER has been #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_PURE) // Use the classic function because /clr:pure lacks the MSVC __fastfail intrinsic: +#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