@@ -265,7 +265,7 @@ namespace details
265265
266266// Unsafe conversion where failure results in fail fast.
267267template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_no_wchar_v<NewT, OldT>, int > = 0 >
268- NewT safe_cast_failfast (const OldT var)
268+ _Out_range_ (==, var) NewT safe_cast_failfast (const OldT var)
269269{
270270 NewT newVar;
271271 FAIL_FAST_IF_FAILED ((details::intsafe_conversion<OldT, NewT>(var, &newVar)));
@@ -274,7 +274,7 @@ NewT safe_cast_failfast(const OldT var)
274274
275275// Unsafe conversion where failure results in fail fast.
276276template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_from_wchar_v<NewT, OldT>, int > = 0 >
277- NewT safe_cast_failfast (const OldT var)
277+ _Out_range_ (==, var) NewT safe_cast_failfast (const OldT var)
278278{
279279 NewT newVar;
280280 FAIL_FAST_IF_FAILED ((details::intsafe_conversion<unsigned short , NewT>(static_cast <unsigned short >(var), &newVar)));
@@ -283,7 +283,7 @@ NewT safe_cast_failfast(const OldT var)
283283
284284// Unsafe conversion where failure results in fail fast.
285285template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_to_wchar_v<NewT, OldT>, int > = 0 >
286- NewT safe_cast_failfast (const OldT var)
286+ _Out_range_ (==, var) NewT safe_cast_failfast (const OldT var)
287287{
288288 unsigned short newVar;
289289 FAIL_FAST_IF_FAILED ((details::intsafe_conversion<OldT, unsigned short >(var, &newVar)));
@@ -292,15 +292,15 @@ NewT safe_cast_failfast(const OldT var)
292292
293293// This conversion is always safe, therefore a static_cast is fine.
294294template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_safe_static_cast_v<NewT, OldT>, int > = 0 >
295- NewT safe_cast_failfast (const OldT var)
295+ _Out_range_ (==, var) NewT safe_cast_failfast (const OldT var)
296296{
297297 return static_cast <NewT>(var);
298298}
299299
300300#ifdef WIL_ENABLE_EXCEPTIONS
301301// Unsafe conversion where failure results in a thrown exception.
302302template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_no_wchar_v<NewT, OldT>, int > = 0 >
303- NewT safe_cast (const OldT var)
303+ _Out_range_ (==, var) NewT safe_cast(const OldT var)
304304{
305305 NewT newVar;
306306 THROW_IF_FAILED ((details::intsafe_conversion<OldT, NewT>(var, &newVar)));
@@ -309,7 +309,7 @@ NewT safe_cast(const OldT var)
309309
310310// Unsafe conversion where failure results in a thrown exception.
311311template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_from_wchar_v<NewT, OldT>, int > = 0 >
312- NewT safe_cast (const OldT var)
312+ _Out_range_ (==, var) NewT safe_cast(const OldT var)
313313{
314314 NewT newVar;
315315 THROW_IF_FAILED ((details::intsafe_conversion<unsigned short , NewT>(static_cast <unsigned short >(var), &newVar)));
@@ -318,7 +318,7 @@ NewT safe_cast(const OldT var)
318318
319319// Unsafe conversion where failure results in a thrown exception.
320320template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_to_wchar_v<NewT, OldT>, int > = 0 >
321- NewT safe_cast (const OldT var)
321+ _Out_range_ (==, var) NewT safe_cast(const OldT var)
322322{
323323 unsigned short newVar;
324324 THROW_IF_FAILED ((details::intsafe_conversion<OldT, unsigned short >(var, &newVar)));
@@ -327,43 +327,43 @@ NewT safe_cast(const OldT var)
327327
328328// This conversion is always safe, therefore a static_cast is fine.
329329template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_safe_static_cast_v<NewT, OldT>, int > = 0 >
330- NewT safe_cast (const OldT var)
330+ _Out_range_ (==, var) NewT safe_cast(const OldT var)
331331{
332332 return static_cast <NewT>(var);
333333}
334334#endif
335335
336336// This conversion is unsafe, therefore the two parameter version of safe_cast_nothrow must be used
337337template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_v<NewT, OldT>, int > = 0 >
338- NewT safe_cast_nothrow (const OldT /* var*/ )
338+ _Out_range_ (==, _Param_( 1 )) NewT safe_cast_nothrow (const OldT /* var*/ )
339339{
340340 static_assert (!wistd::is_same_v<NewT, NewT>, " This cast has the potential to fail, use the two parameter safe_cast_nothrow instead" );
341341}
342342
343343// This conversion is always safe, therefore a static_cast is fine.
344344template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_safe_static_cast_v<NewT, OldT>, int > = 0 >
345- NewT safe_cast_nothrow (const OldT var)
345+ _Out_range_ (==, var) NewT safe_cast_nothrow (const OldT var)
346346{
347347 return static_cast <NewT>(var);
348348}
349349
350350// Unsafe conversion where an HRESULT is returned. It is up to the callee to check and handle the HRESULT
351351template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_no_wchar_v<NewT, OldT>, int > = 0 >
352- HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
352+ _At_ (*newTResult, _Out_range_(==, var)) HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
353353{
354354 return details::intsafe_conversion<OldT, NewT>(var, newTResult);
355355}
356356
357357// Unsafe conversion where an HRESULT is returned. It is up to the callee to check and handle the HRESULT
358358template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_from_wchar_v<NewT, OldT>, int > = 0 >
359- HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
359+ _At_ (*newTResult, _Out_range_(==, var)) HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
360360{
361361 return details::intsafe_conversion<unsigned short , NewT>(static_cast <unsigned short >(var), newTResult);
362362}
363363
364364// Unsafe conversion where an HRESULT is returned. It is up to the callee to check and handle the HRESULT
365365template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_unsafe_cast_to_wchar_v<NewT, OldT>, int > = 0 >
366- HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
366+ _At_ (*newTResult, _Out_range_(==, var)) HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
367367{
368368 return details::intsafe_conversion<OldT, unsigned short >(var, reinterpret_cast <unsigned short *>(newTResult));
369369}
@@ -372,7 +372,7 @@ HRESULT safe_cast_nothrow(const OldT var, NewT* newTResult)
372372// does not involve a variably sized type, then the compilation will fail and say the single parameter version
373373// of safe_cast_nothrow should be used instead.
374374template <typename NewT, typename OldT, wistd::enable_if_t <details::is_supported_safe_static_cast_v<NewT, OldT>, int > = 0 >
375- HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
375+ _At_ (*newTResult, _Out_range_(==, var)) HRESULT safe_cast_nothrow (const OldT var, NewT* newTResult)
376376{
377377 static_assert (
378378 details::is_potentially_variably_sized_cast_v<OldT, NewT>,
@@ -389,7 +389,7 @@ HRESULT safe_cast_nothrow(const OldT var, NewT* newTResult)
389389// wil::safe_zero_extending_cast<ULONG_PTR>(-1)
390390// will return 0x00000000`FFFFFFFF on a 64-bit system.
391391template <typename NewT, typename OldT, wistd::enable_if_t <details::is_sign_extending_cast_v<NewT, OldT>, int > = 0 >
392- NewT safe_zero_extending_cast (const OldT var)
392+ _Out_range_ (==, var) NewT safe_zero_extending_cast (const OldT var)
393393{
394394 // The first cast is to an unsigned type of the same size as the original. The second cast is to the
395395 // larger type. Being an unsigned cast, the upper bits are zeroed out.
0 commit comments