diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 5e973ade480..c078de097fc 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -1379,8 +1379,8 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer constexpr basic_string_view( _In_reads_(_Count) const const_pointer _Cts, const size_type _Count) noexcept // strengthened : _Mydata(_Cts), _Mysize(_Count) { -#if _CONTAINER_DEBUG_LEVEL > 0 - _STL_VERIFY(_Count == 0 || _Cts, "non-zero size null string_view"); +#if _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(_Count == 0 || _Cts, "cannot construct a string_view from a null pointer and a non-zero size"); #endif } @@ -1474,7 +1474,7 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer } _NODISCARD constexpr const_reference operator[](const size_type _Off) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < _Mysize, "string_view subscript out of range"); #endif @@ -1489,31 +1489,35 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer } _NODISCARD constexpr const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize != 0, "front() called on empty string_view"); #endif + return _Mydata[0]; } _NODISCARD constexpr const_reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize != 0, "back() called on empty string_view"); #endif + return _Mydata[_Mysize - 1]; } constexpr void remove_prefix(const size_type _Count) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize >= _Count, "cannot remove_prefix() larger than string_view size"); #endif + _Mydata += _Count; _Mysize -= _Count; } constexpr void remove_suffix(const size_type _Count) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize >= _Count, "cannot remove_suffix() larger than string_view size"); #endif + _Mysize -= _Count; } diff --git a/stl/inc/array b/stl/inc/array index 77bf40f14f1..5be4b29622d 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -531,7 +531,7 @@ public: } _NODISCARD _CONSTEXPR17 reference operator[](_In_range_(<, _Size) size_type _Pos) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pos < _Size, "array subscript out of range"); #endif @@ -540,7 +540,7 @@ public: _NODISCARD constexpr const_reference operator[](_In_range_(<, _Size) size_type _Pos) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pos < _Size, "array subscript out of range"); #endif @@ -707,7 +707,7 @@ public: } _NODISCARD reference operator[](size_type) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_REPORT_ERROR("array subscript is invalid"); #endif @@ -715,7 +715,7 @@ public: } _NODISCARD const_reference operator[](size_type) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_REPORT_ERROR("array subscript is invalid"); #endif @@ -723,7 +723,7 @@ public: } _NODISCARD reference front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_REPORT_ERROR("array::front() is invalid"); #endif @@ -731,7 +731,7 @@ public: } _NODISCARD const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_REPORT_ERROR("array::front() is invalid"); #endif @@ -739,7 +739,7 @@ public: } _NODISCARD reference back() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_REPORT_ERROR("array::back() is invalid"); #endif @@ -747,7 +747,7 @@ public: } _NODISCARD const_reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_REPORT_ERROR("array::back() is invalid"); #endif diff --git a/stl/inc/bitset b/stl/inc/bitset index 7374ea0676b..7792605af47 100644 --- a/stl/inc/bitset +++ b/stl/inc/bitset @@ -116,14 +116,6 @@ public: }; private: - static constexpr void _Validate(const size_t _Pos) noexcept { // verify that _Pos is within bounds -#if _ITERATOR_DEBUG_LEVEL == 0 - (void) _Pos; -#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 / _ITERATOR_DEBUG_LEVEL != 0 vvv - _STL_VERIFY(_Pos < _Bits, "bitset subscript out of range"); -#endif // ^^^ _ITERATOR_DEBUG_LEVEL != 0 ^^^ - } - constexpr bool _Subscript(size_t _Pos) const noexcept { return (_Array[_Pos / _Bitsperword] & (_Ty{1} << _Pos % _Bitsperword)) != 0; } @@ -133,12 +125,18 @@ private: public: _NODISCARD constexpr bool operator[](const size_t _Pos) const noexcept /* strengthened */ { - _Validate(_Pos); +#if _MSVC_STL_HARDENING_BITSET || _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(_Pos < _Bits, "bitset subscript out of range"); +#endif + return _Subscript(_Pos); } _NODISCARD _CONSTEXPR23 reference operator[](const size_t _Pos) noexcept /* strengthened */ { - _Validate(_Pos); +#if _MSVC_STL_HARDENING_BITSET || _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(_Pos < _Bits, "bitset subscript out of range"); +#endif + return reference(*this, _Pos); } diff --git a/stl/inc/deque b/stl/inc/deque index cab1a2a804e..b6fcee81c38 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1063,7 +1063,7 @@ public: } _NODISCARD const_reference operator[](size_type _Pos) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pos < _Mysize(), "deque subscript out of range"); #endif @@ -1071,7 +1071,7 @@ public: } _NODISCARD reference operator[](size_type _Pos) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pos < _Mysize(), "deque subscript out of range"); #endif @@ -1095,7 +1095,7 @@ public: } _NODISCARD reference front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!empty(), "front() called on empty deque"); #endif @@ -1103,7 +1103,7 @@ public: } _NODISCARD const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!empty(), "front() called on empty deque"); #endif @@ -1111,7 +1111,7 @@ public: } _NODISCARD reference back() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!empty(), "back() called on empty deque"); #endif @@ -1119,7 +1119,7 @@ public: } _NODISCARD const_reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!empty(), "back() called on empty deque"); #endif @@ -1473,47 +1473,34 @@ private: public: void pop_front() noexcept /* strengthened */ { +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(!empty(), "pop_front() called on empty deque"); +#endif + #if _ITERATOR_DEBUG_LEVEL == 2 - if (empty()) { - _STL_REPORT_ERROR("pop_front() called on empty deque"); - } else { // something to erase, do it - _Orphan_off(_Myoff()); - _Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Myoff())); - if (--_Mysize() == 0) { - _Myoff() = 0; - } else { - ++_Myoff(); - } - } -#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 / _ITERATOR_DEBUG_LEVEL < 2 vvv + _Orphan_off(_Myoff()); +#endif _Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Myoff())); if (--_Mysize() == 0) { _Myoff() = 0; } else { ++_Myoff(); } -#endif // ^^^ _ITERATOR_DEBUG_LEVEL < 2 ^^^ } void pop_back() noexcept /* strengthened */ { -#if _ITERATOR_DEBUG_LEVEL == 2 - if (empty()) { - _STL_REPORT_ERROR("pop_back() called on empty deque"); - } else { // something to erase, do it - size_type _Newoff = _Myoff() + _Mysize() - 1; - _Orphan_off(_Newoff); - _Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Newoff)); - if (--_Mysize() == 0) { - _Myoff() = 0; - } - } -#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 / _ITERATOR_DEBUG_LEVEL < 2 vvv +#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(!empty(), "pop_back() called on empty deque"); +#endif + size_type _Newoff = _Myoff() + _Mysize() - 1; +#if _ITERATOR_DEBUG_LEVEL == 2 + _Orphan_off(_Newoff); +#endif _Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Newoff)); if (--_Mysize() == 0) { _Myoff() = 0; } -#endif // ^^^ _ITERATOR_DEBUG_LEVEL < 2 ^^^ } iterator erase(const_iterator _Where) noexcept(is_nothrow_move_assignable_v) /* strengthened */ { diff --git a/stl/inc/expected b/stl/inc/expected index 45eb51a5fb6..4080ad8b5ef 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -620,40 +620,46 @@ public: // [expected.object.obs] _NODISCARD constexpr const _Ty* operator->() const noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator->() called on a std::expected that contains an error, not a value"); #endif + return _STD addressof(_Value); } _NODISCARD constexpr _Ty* operator->() noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator->() called on a std::expected that contains an error, not a value"); #endif + return _STD addressof(_Value); } _NODISCARD constexpr const _Ty& operator*() const& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value"); #endif + return _Value; } _NODISCARD constexpr _Ty& operator*() & noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value"); #endif + return _Value; } _NODISCARD constexpr const _Ty&& operator*() const&& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value"); #endif + return _STD move(_Value); } _NODISCARD constexpr _Ty&& operator*() && noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value"); #endif + return _STD move(_Value); } @@ -706,27 +712,31 @@ public: } _NODISCARD constexpr const _Err& error() const& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _Unexpected; } _NODISCARD constexpr _Err& error() & noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _Unexpected; } _NODISCARD constexpr const _Err&& error() const&& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _STD move(_Unexpected); } _NODISCARD constexpr _Err&& error() && noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _STD move(_Unexpected); } @@ -1468,7 +1478,7 @@ public: } constexpr void operator*() const noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value"); #endif } @@ -1489,27 +1499,31 @@ public: } _NODISCARD constexpr const _Err& error() const& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _Unexpected; } _NODISCARD constexpr _Err& error() & noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _Unexpected; } _NODISCARD constexpr const _Err&& error() const&& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _STD move(_Unexpected); } _NODISCARD constexpr _Err&& error() && noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error"); #endif + return _STD move(_Unexpected); } diff --git a/stl/inc/forward_list b/stl/inc/forward_list index 3e801e48e23..f0fb5398ef5 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -900,7 +900,7 @@ public: } _NODISCARD reference front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_FORWARD_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Myhead != nullptr, "front() called on empty forward_list"); #endif @@ -908,7 +908,7 @@ public: } _NODISCARD const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_FORWARD_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Myhead != nullptr, "front() called on empty forward_list"); #endif @@ -927,6 +927,10 @@ public: #endif // _HAS_CXX23 void pop_front() noexcept /* strengthened */ { +#if _MSVC_STL_HARDENING_FORWARD_LIST || _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(_Mypair._Myval2._Myhead != nullptr, "pop_front() called on empty forward_list"); +#endif + _Erase_after(_Mypair._Myval2._Before_head()); } diff --git a/stl/inc/generator b/stl/inc/generator index 09c16afc339..69aa0d5b816 100644 --- a/stl/inc/generator +++ b/stl/inc/generator @@ -477,14 +477,14 @@ namespace _Gen_detail { _NODISCARD _Ref operator*() const noexcept(noexcept(static_cast<_Ref>(*_Coro.promise()._Get_top().promise()._Ptr))) /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Coro.done(), "Can't dereference generator end iterator"); #endif return static_cast<_Ref>(*_Coro.promise()._Get_top().promise()._Ptr); } _Iterator& operator++() { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_Coro.done(), "Can't increment generator end iterator"); #endif _Coro.promise()._Get_top().resume(); @@ -565,7 +565,7 @@ public: _NODISCARD _Gen_detail::_Iter_provider<_Value, _Ref>::_Iterator begin() { // Pre: _Coro is suspended at its initial suspend point -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Coro, "Can't call begin on moved-from generator"); #endif _Coro.resume(); diff --git a/stl/inc/list b/stl/inc/list index fc5093dca87..1d67c2e4810 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -1208,7 +1208,7 @@ public: } _NODISCARD reference front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "front() called on empty list"); #endif @@ -1216,7 +1216,7 @@ public: } _NODISCARD const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "front() called on empty list"); #endif @@ -1224,7 +1224,7 @@ public: } _NODISCARD reference back() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "back() called on empty list"); #endif @@ -1232,7 +1232,7 @@ public: } _NODISCARD const_reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "back() called on empty list"); #endif @@ -1253,7 +1253,7 @@ public: #endif // _HAS_CXX23 void pop_front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "pop_front() called on empty list"); #endif @@ -1274,7 +1274,7 @@ public: #endif // _HAS_CXX23 void pop_back() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_LIST || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "pop_back() called on empty list"); #endif diff --git a/stl/inc/mdspan b/stl/inc/mdspan index 714c6120c71..bedc6046035 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -100,7 +100,7 @@ private: _STL_INTERNAL_STATIC_ASSERT(sizeof...(_OtherExtents) == _Rank); _STL_INTERNAL_STATIC_ASSERT( ((_OtherExtents == dynamic_extent || _Extents == dynamic_extent || _OtherExtents == _Extents) && ...)); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (rank() > 0) { for (rank_type _Idx = 0; _Idx < _Rank; ++_Idx) { if constexpr (rank() != rank_dynamic()) { @@ -114,7 +114,7 @@ private: "r (N4950 [mdspan.extents.cons]/2.2)"); } } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template @@ -126,7 +126,7 @@ private: requires (tuple_size_v<_ExtsTuple> != _Rank_dynamic) constexpr explicit extents(_Extents_from_tuple, _ExtsTuple _Tpl, index_sequence<_DynIndices...>) noexcept : _Base{static_cast(_STD move(_STD get<_Dynamic_indices_inv[_DynIndices]>(_Tpl)))...} { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 [&](index_sequence<_MixedIndices...>) { _STL_VERIFY(((_Static_extents[_MixedIndices] == dynamic_extent || _STD cmp_equal(_Static_extents[_MixedIndices], @@ -135,7 +135,7 @@ private: "Value of exts_arr[r] must be equal to extent(r) for each r for which extent(r) is a static extent " "(N4950 [mdspan.extents.cons]/7.1)"); }(make_index_sequence{}); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template @@ -143,13 +143,13 @@ private: : _Base{static_cast(_STD as_const(_Dynamic_exts[_Indices]))...} { _STL_INTERNAL_STATIC_ASSERT(is_convertible_v && is_nothrow_constructible_v); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Is_standard_integer<_OtherIndexType> && _Rank_dynamic != 0) { _STL_VERIFY(((_Dynamic_exts[_Indices] >= 0 && _STD in_range(_Dynamic_exts[_Indices])) && ...), "exts[r] must be representable as a nonnegative value of type index_type for every rank index r " "(N4950 [mdspan.extents.cons]/10.2)"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template @@ -158,7 +158,7 @@ private: _STL_INTERNAL_STATIC_ASSERT(_Size != _Rank_dynamic); _STL_INTERNAL_STATIC_ASSERT(is_convertible_v && is_nothrow_constructible_v); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Is_standard_integer<_OtherIndexType>) { for (rank_type _Idx = 0; _Idx < _Rank; ++_Idx) { _STL_VERIFY( @@ -170,7 +170,7 @@ private: "(N4950 [mdspan.extents.cons]/10.2)"); } } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } public: @@ -183,14 +183,14 @@ public: } _NODISCARD static constexpr size_t static_extent(_In_range_(<, _Rank) const rank_type _Idx) noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Idx < _Rank, "Index must be less than rank() (N4950 [mdspan.extents.obs]/1)"); #endif return _Static_extents[_Idx]; } _NODISCARD constexpr index_type extent(_In_range_(<, _Rank) const rank_type _Idx) const noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Idx < _Rank, "Index must be less than rank() (N4950 [mdspan.extents.obs]/3)"); #endif if constexpr (rank_dynamic() == 0) { @@ -222,7 +222,7 @@ public: && (sizeof...(_OtherIndexTypes) == rank_dynamic() || sizeof...(_OtherIndexTypes) == rank()) constexpr explicit extents(_OtherIndexTypes... _Exts) noexcept : extents(_Extents_from_tuple{}, _STD tie(_Exts...), make_index_sequence{}) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 auto _Check_extent = [](const _Ty& _Ext) { if constexpr (_Is_standard_integer<_Ty>) { return _Ext >= 0 && _STD in_range(_Ext); @@ -235,7 +235,7 @@ public: }; _STL_VERIFY((_Check_extent(_Exts) && ...), "Each argument must be representable as a nonnegative value of type " "index_type (N4950 [mdspan.extents.cons]/7.2)"); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template @@ -463,7 +463,7 @@ struct _Maybe_fully_static_extents<_Extents> { template constexpr explicit _Maybe_fully_static_extents([[maybe_unused]] const _OtherExtents& _Exts_) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 (void) _Extents{_Exts_}; // NB: temporary created for preconditions check #endif } @@ -495,13 +495,13 @@ public: constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type& _Exts_) noexcept : _Base(_Exts_) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (extents_type::rank_dynamic() != 0) { _STL_VERIFY(_Exts_._Is_dynamic_multidim_index_space_size_representable(), "The size of the multidimensional index space e must be representable as a value of type index_type " "(N4950 [mdspan.layout.left.cons]/1)."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template @@ -509,7 +509,7 @@ public: constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) mapping(const mapping<_OtherExtents>& _Other) noexcept : _Base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.left.cons]/4)."); @@ -521,7 +521,7 @@ public: constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) mapping(const layout_right::mapping<_OtherExtents>& _Other) noexcept : _Base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.left.cons]/7)."); @@ -533,7 +533,7 @@ public: constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<_OtherExtents>& _Other) noexcept // strengthened : _Base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (extents_type::rank() > 0) { index_type _Prod = 1; for (size_t _Idx = 0; _Idx < extents_type::_Rank; ++_Idx) { @@ -546,7 +546,7 @@ public: _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.left.cons]/10.2)."); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } constexpr mapping& operator=(const mapping&) noexcept = default; @@ -594,7 +594,7 @@ public: _NODISCARD constexpr index_type stride(_In_range_(<, extents_type::_Rank) const rank_type _Idx) const noexcept requires (extents_type::rank() > 0) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Idx < extents_type::_Rank, "Value of i must be less than extents_type::rank() (N4950 [mdspan.layout.left.obs]/6)."); #endif @@ -612,7 +612,7 @@ private: _NODISCARD constexpr index_type _Index_impl( [[maybe_unused]] index_sequence<_Seq...> _Index_seq, _IndexTypes... _Indices) const noexcept { _STL_INTERNAL_STATIC_ASSERT(conjunction_v...>); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Exts._Contains_multidimensional_index(_Index_seq, _Indices...), "Value of extents_type::index-cast(i) must be a multidimensional index in extents_ (N4950 " "[mdspan.layout.left.obs]/3)."); @@ -649,13 +649,13 @@ public: constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type& _Exts_) noexcept : _Base(_Exts_) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (extents_type::rank_dynamic() != 0) { _STL_VERIFY(_Exts_._Is_dynamic_multidim_index_space_size_representable(), "The size of the multidimensional index space e must be representable as a value of type index_type " "(N4950 [mdspan.layout.right.cons]/1)."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template @@ -663,7 +663,7 @@ public: constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) mapping(const mapping<_OtherExtents>& _Other) noexcept : _Base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.right.cons]/4)."); @@ -675,7 +675,7 @@ public: constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) mapping(const layout_left::mapping<_OtherExtents>& _Other) noexcept : _Base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.right.cons]/7)."); @@ -686,7 +686,7 @@ public: requires is_constructible_v constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<_OtherExtents>& _Other) noexcept : _Base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (extents_type::rank() > 0) { index_type _Prod = 1; for (size_t _Idx = extents_type::_Rank; _Idx-- > 0;) { @@ -699,7 +699,7 @@ public: _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.right.cons]/10.2)."); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } constexpr mapping& operator=(const mapping&) noexcept = default; @@ -747,7 +747,7 @@ public: _NODISCARD constexpr index_type stride(_In_range_(<, extents_type::_Rank) const rank_type _Idx) const noexcept requires (extents_type::rank() > 0) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Idx < extents_type::_Rank, "Value of i must be less than extents_type::rank() (N4950 [mdspan.layout.right.obs]/6)."); #endif @@ -765,7 +765,7 @@ private: _NODISCARD constexpr index_type _Index_impl( [[maybe_unused]] index_sequence<_Seq...> _Index_seq, _IndexTypes... _Indices) const noexcept { _STL_INTERNAL_STATIC_ASSERT(conjunction_v...>); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Exts._Contains_multidimensional_index(_Index_seq, _Indices...), "Value of extents_type::index-cast(i) must be a multidimensional index in extents_ (N4950 " "[mdspan.layout.right.obs]/3)."); @@ -815,7 +815,7 @@ private: : _Extents_base(_Exts_), _Strides_base{static_cast(_STD as_const(_Strides_[_Indices]))...} { _STL_INTERNAL_STATIC_ASSERT(is_convertible_v && is_nothrow_constructible_v); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (extents_type::rank() != 0) { bool _Found_zero = false; bool _Overflow = false; @@ -838,7 +838,7 @@ private: _STL_VERIFY(_Found_zero || !_Overflow, "REQUIRED-SPAN-SIZE(e, s) must be representable as a value of type " "index_type (N4950 [mdspan.layout.stride.cons]/4.2)."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } public: @@ -846,7 +846,7 @@ public: if constexpr (extents_type::rank() != 0) { this->_Array.back() = 1; for (rank_type _Idx = extents_type::_Rank - 1; _Idx-- > 0;) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 const bool _Overflow = _Mul_overflow(this->_Array[_Idx + 1], this->_Exts.extent(_Idx + 1), this->_Array[_Idx]); // NB: N4950 requires value of 'layout_right::mapping().required_span_size()' to be @@ -855,9 +855,9 @@ public: _STL_VERIFY(!_Overflow, "Value of layout_right::mapping().required_span_size() must be " "representable as a value of type index_type (N4950 [mdspan.layout.stride.cons]/1)."); -#else // ^^^ _CONTAINER_DEBUG_LEVEL > 0 / _CONTAINER_DEBUG_LEVEL == 0 vvv +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv this->_Array[_Idx] = static_cast(this->_Array[_Idx + 1] * this->_Exts.extent(_Idx + 1)); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ } } } @@ -887,17 +887,17 @@ public: || _Is_mapping_of) )) mapping(const _StridedLayoutMapping& _Other) noexcept : _Extents_base(_Other.extents()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " "[mdspan.layout.stride.cons]/7.3)."); _STL_VERIFY( _Offset(_Other) == 0, "Value of OFFSET(other) must be equal to 0 (N4950 [mdspan.layout.stride.cons]/7.4)."); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 if constexpr (extents_type::_Rank != 0) { for (rank_type _Idx = 0; _Idx < extents_type::_Rank; ++_Idx) { const auto _Stride = _Other.stride(_Idx); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Stride > 0, "Value of other.stride(r) must be greater than 0 for every rank index r of " "extents() (N4950 [mdspan.layout.stride.cons]/7.2)."); #endif @@ -980,7 +980,7 @@ public: _STL_REPORT_ERROR("The argument to stride must be nonnegative and less than extents_type::rank()."); return 1; } else { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Idx < extents_type::_Rank, "The argument to stride must be nonnegative and less than extents_type::rank()."); #endif @@ -1028,7 +1028,7 @@ private: _NODISCARD constexpr index_type _Index_impl( [[maybe_unused]] index_sequence<_Seq...> _Index_seq, _IndexTypes... _Indices) const noexcept { _STL_INTERNAL_STATIC_ASSERT(conjunction_v...>); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Exts._Contains_multidimensional_index(_Index_seq, _Indices...), "Value of extents_type::index-cast(i) must be a multidimensional index in extents_ (N4950 " "[mdspan.layout.stride.obs]/3)."); @@ -1142,7 +1142,7 @@ struct _Mdspan_accessor_base<_AccessorPolicy> { static constexpr _AccessorPolicy _Acc{}; }; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 template _NODISCARD constexpr _IndexType _Mdspan_checked_index_cast(_OtherIndexType&& _Idx) noexcept(is_nothrow_constructible_v<_IndexType, _OtherIndexType>) { @@ -1156,7 +1156,7 @@ _NODISCARD constexpr _IndexType _Mdspan_checked_index_cast(_OtherIndexType&& _Id } return static_cast<_IndexType>(_STD forward<_OtherIndexType>(_Idx)); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 _EXPORT_STD template > @@ -1201,7 +1201,7 @@ public: } _NODISCARD static constexpr size_t static_extent(_In_range_(<, extents_type::_Rank) const rank_type _Idx) noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Idx < extents_type::_Rank, "Index must be less than rank() (N4950 [mdspan.extents.obs]/1)"); #endif return extents_type::_Static_extents[_Idx]; @@ -1286,14 +1286,14 @@ public: "[mdspan.mdspan.cons]/20.1)."); static_assert(is_constructible_v, "The extents_type must be constructible from OtherExtents (N4950 [mdspan.mdspan.cons]/20.2)."); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_MDSPAN || _ITERATOR_DEBUG_LEVEL != 0 for (rank_type _Idx = 0; _Idx < extents_type::_Rank; ++_Idx) { const auto _Static_ext = extents_type::_Static_extents[_Idx]; _STL_VERIFY(_STD cmp_equal(_Static_ext, dynamic_extent) || _STD cmp_equal(_Static_ext, _Other.extent(_Idx)), "For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == " "other.extent(r) must be true (N4950 [mdspan.mdspan.cons]/21.1)."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_MDSPAN || _ITERATOR_DEBUG_LEVEL != 0 } constexpr mdspan& operator=(const mdspan&) = default; @@ -1306,11 +1306,11 @@ public: && (sizeof...(_OtherIndexTypes) == rank()) _NODISCARD constexpr reference operator[](_OtherIndexTypes... _Indices) const noexcept(noexcept(_Access_impl(static_cast(_STD move(_Indices))...))) /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 return _Access_impl(_STD _Mdspan_checked_index_cast(_STD move(_Indices))...); -#else // ^^^ _CONTAINER_DEBUG_LEVEL > 0 / _CONTAINER_DEBUG_LEVEL <= 0 vvv +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv return _Access_impl(static_cast(_STD move(_Indices))...); -#endif // ^^^ _CONTAINER_DEBUG_LEVEL <= 0 ^^^ +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ } #endif // ^^^ defined(__cpp_multidimensional_subscript) ^^^ @@ -1319,11 +1319,11 @@ private: _NODISCARD constexpr reference _Multidimensional_subscript( span<_OtherIndexType, rank()> _Indices, index_sequence<_Seq...>) const noexcept(noexcept(_Access_impl(static_cast(_STD as_const(_Indices[_Seq]))...))) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 return _Access_impl(_STD _Mdspan_checked_index_cast(_STD as_const(_Indices[_Seq]))...); -#else // ^^^ _CONTAINER_DEBUG_LEVEL > 0 / _CONTAINER_DEBUG_LEVEL <= 0 vvv +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv return _Access_impl(static_cast(_STD as_const(_Indices[_Seq]))...); -#endif // ^^^ _CONTAINER_DEBUG_LEVEL <= 0 ^^^ +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ } public: @@ -1344,13 +1344,13 @@ public: } _NODISCARD constexpr size_type size() const noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (rank_dynamic() != 0) { _STL_VERIFY(this->_Map.extents().template _Is_dynamic_multidim_index_space_size_representable(), "The size of the multidimensional index space extents() must be representable as a value of type " "size_type (N4950 [mdspan.mdspan.members]/7)."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 return static_cast( _Fwd_prod_of_extents::_Calculate(this->_Map.extents(), extents_type::_Rank)); } @@ -1434,7 +1434,7 @@ private: _NODISCARD constexpr reference _Access_impl(_OtherIndexTypes... _Indices) const noexcept(noexcept(this->_Acc.access(_Ptr, static_cast(this->_Map(_Indices...))))) { _STL_INTERNAL_STATIC_ASSERT(conjunction_v...>); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_MDSPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Map.extents()._Contains_multidimensional_index(make_index_sequence{}, _Indices...), "mdspan subscript out of range; extents_type::index-cast(std::move(indices)) must be " "a multidimensional index in extents() (N5001 [mdspan.mdspan.members]/3)."); diff --git a/stl/inc/mutex b/stl/inc/mutex index 0daa8314b5b..3f5ab3d1b7e 100644 --- a/stl/inc/mutex +++ b/stl/inc/mutex @@ -584,12 +584,12 @@ public: cv_status wait_until(unique_lock& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time) { // wait until time point static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY( _Lck.owns_lock(), "wait_until's caller must own the lock argument (N4958 [thread.condition.condvar]/17)"); _STL_VERIFY(_Mtx_current_owns(_Lck.mutex()->_Mymtx()), "wait_until's calling thread must hold the lock argument's mutex (N4958 [thread.condition.condvar]/17)"); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 for (;;) { const auto _Now = _Clock::now(); if (_Abs_time <= _Now) { diff --git a/stl/inc/optional b/stl/inc/optional index 7a527fff616..196374892eb 100644 --- a/stl/inc/optional +++ b/stl/inc/optional @@ -181,30 +181,34 @@ struct _Optional_construct_base : _Optional_destruct_base<_Ty> { } _NODISCARD constexpr _Ty& operator*() & noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_OPTIONAL || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Has_value, "operator*() called on empty optional"); #endif + return this->_Value; } _NODISCARD constexpr const _Ty& operator*() const& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_OPTIONAL || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Has_value, "operator*() called on empty optional"); #endif + return this->_Value; } _NODISCARD constexpr _Ty&& operator*() && noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_OPTIONAL || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Has_value, "operator*() called on empty optional"); #endif + return _STD move(this->_Value); } _NODISCARD constexpr const _Ty&& operator*() const&& noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_OPTIONAL || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Has_value, "operator*() called on empty optional"); #endif + return _STD move(this->_Value); } }; @@ -376,15 +380,17 @@ public: } _NODISCARD constexpr const _Ty* operator->() const noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_OPTIONAL || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Has_value, "operator->() called on empty optional"); #endif + return _STD addressof(this->_Value); } _NODISCARD constexpr _Ty* operator->() noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_OPTIONAL || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Has_value, "operator->() called on empty optional"); #endif + return _STD addressof(this->_Value); } diff --git a/stl/inc/ranges b/stl/inc/ranges index 3af972f8847..4ded5ba5f56 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -959,34 +959,34 @@ namespace ranges { constexpr explicit iota_view(_Wi _Value_) noexcept(is_nothrow_move_constructible_v<_Wi> && is_nothrow_default_constructible_v<_Bo>) // strengthened : _Value(_STD move(_Value_)) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (totally_ordered_with<_Wi, _Bo>) { _STL_VERIFY(_Value_ <= _Bound, "Per N4981 [range.iota.view]/6, the first argument must not exceed the " "value-initialized bound when their types are totally ordered."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } constexpr explicit iota_view(type_identity_t<_Wi> _Value_, type_identity_t<_Bo> _Bound_) noexcept(is_nothrow_move_constructible_v<_Wi> && is_nothrow_move_constructible_v<_Bo>) // strengthened : _Value(_STD move(_Value_)), _Bound(_STD move(_Bound_)) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (totally_ordered_with<_Wi, _Bo>) { _STL_VERIFY(_Value_ <= _Bound_, "Per N4981 [range.iota.view]/8, the first argument must not exceed the " "second when their types are totally ordered."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } constexpr explicit iota_view(_It _First, _Se _Last) noexcept(is_nothrow_move_constructible_v<_Wi> && is_nothrow_move_constructible_v<_Bo>) // strengthened : _Value(_STD move(_First._Current)), _Bound(_STD move(_Bound_from(_Last))) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (totally_ordered_with<_Wi, _Bo>) { _STL_VERIFY(_Value <= _Bound, "Per N4981 [range.iota.view]/8 and /10, the iterator must not exceed the " "sentinel when their types are totally ordered."); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } _NODISCARD constexpr _It begin() const noexcept(is_nothrow_copy_constructible_v<_Wi>) /* strengthened */ { @@ -1109,7 +1109,7 @@ namespace ranges { } constexpr _Iterator& operator++() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Current < (numeric_limits<_Index_type>::max)(), "cannot increment repeat_view iterator past end (integer overflow)"); #endif @@ -1123,14 +1123,14 @@ namespace ranges { } constexpr _Iterator& operator--() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (is_same_v<_Bo, unreachable_sentinel_t>) { _STL_VERIFY(_Current > (numeric_limits<_Index_type>::min)(), "cannot decrement repeat_view iterator before begin (integer overflow)"); } else { _STL_VERIFY(_Current > 0, "cannot decrement below 0"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 --_Current; return *this; } @@ -1141,7 +1141,7 @@ namespace ranges { } constexpr _Iterator& operator+=(difference_type _Off) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#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)" @@ -1159,12 +1159,12 @@ namespace ranges { if constexpr (!is_same_v<_Bo, unreachable_sentinel_t>) { _STL_VERIFY(_Current + _Off >= 0, "cannot subtract below 0"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 _Current += static_cast<_Index_type>(_Off); return *this; } constexpr _Iterator& operator-=(difference_type _Off) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#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)" @@ -1182,7 +1182,7 @@ namespace ranges { if constexpr (!is_same_v<_Bo, unreachable_sentinel_t>) { _STL_VERIFY(_Current - _Off >= 0, "cannot subtract below 0"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 _Current -= static_cast<_Index_type>(_Off); return *this; } @@ -1239,20 +1239,20 @@ namespace ranges { noexcept(is_nothrow_copy_constructible_v<_Ty>) // strengthened requires copy_constructible<_Ty> : _Value(in_place, _Value_), _Bound(_STD move(_Bound_)) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Signed_integer_like<_Bo>) { _STL_VERIFY(_Bound >= 0, "Bound must be >= 0"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } _NODISCARD_CTOR constexpr explicit repeat_view(_Ty&& _Value_, _Bo _Bound_ = _Bo{}) noexcept(is_nothrow_move_constructible_v<_Ty>) // strengthened : _Value(in_place, _STD move(_Value_)), _Bound(_STD move(_Bound_)) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Signed_integer_like<_Bo>) { _STL_VERIFY(_Bound >= 0, "Bound must be >= 0"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } template requires constructible_from<_Ty, _TArgs...> && constructible_from<_Bo, _BArgs...> @@ -1261,11 +1261,11 @@ namespace ranges { noexcept(is_nothrow_constructible_v<_Ty, _TArgs...> && noexcept(_STD make_from_tuple<_Bo>(_Bound_args))) // strengthened : repeat_view(_Val_args, index_sequence_for<_TArgs...>{}, _STD make_from_tuple<_Bo>(_Bound_args)) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Signed_integer_like<_Bo>) { _STL_VERIFY(_Bound >= 0, "Bound must be >= 0"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 } _NODISCARD constexpr _Iterator begin() const noexcept /* strengthened */ { @@ -1759,14 +1759,14 @@ namespace ranges { } _NODISCARD constexpr const _Pr& pred() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "filter_view has no predicate"); #endif return *_Pred; } _NODISCARD constexpr _Iterator begin() { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY( _Pred, "N4950 [range.filter.view]/3 forbids calling begin on a filter_view that holds no predicate"); #endif @@ -1915,7 +1915,7 @@ namespace ranges { constexpr explicit take_view(_Vw _Range_, const range_difference_t<_Vw> _Count_) noexcept(is_nothrow_move_constructible_v<_Vw>) // strengthened : _Range(_STD move(_Range_)), _Count{_Count_} { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count_ >= 0, "Number of elements to take must be non-negative (N4971 [range.take.view]/1)"); #endif } @@ -2223,7 +2223,7 @@ namespace ranges { } _NODISCARD constexpr const _Pr& pred() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "take_while_view has no predicate"); #endif return *_Pred; @@ -2245,7 +2245,7 @@ namespace ranges { noexcept(_RANGES end(_Range)) && is_nothrow_move_constructible_v<_Sentinel>) /* strengthened */ requires (!_Simple_view<_Vw>) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "cannot call end on a take_while_view with no predicate"); #endif return _Sentinel{_RANGES end(_Range), _STD addressof(*_Pred)}; @@ -2255,7 +2255,7 @@ namespace ranges { noexcept(_RANGES end(_Range)) && is_nothrow_move_constructible_v<_Sentinel>) /* strengthened */ requires range && indirect_unary_predicate> { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "cannot call end on a take_while_view with no predicate"); #endif return _Sentinel{_RANGES end(_Range), _STD addressof(*_Pred)}; @@ -2335,7 +2335,7 @@ namespace ranges { constexpr explicit drop_view(_Vw _Range_, const range_difference_t<_Vw> _Count_) noexcept(is_nothrow_move_constructible_v<_Vw>) // strengthened : _Range(_STD move(_Range_)), _Count{_Count_} { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count_ >= 0, "Number of elements to drop must be non-negative (N4971 [range.drop.view]/1)"); #endif } @@ -2557,14 +2557,14 @@ namespace ranges { } _NODISCARD constexpr const _Pr& pred() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "drop_while_view has no predicate"); #endif return *_Pred; } _NODISCARD constexpr auto begin() { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY( _Pred, "N4950 [range.drop.while.view]/3 forbids calling begin on a drop_while_view with no predicate"); #endif @@ -4237,7 +4237,7 @@ namespace ranges { requires (input_or_output_iterator> && _Choice<_It>._Strategy != _St::_None) _NODISCARD _STATIC_CALL_OPERATOR constexpr auto operator()(_It&& _First, const iter_difference_t> _Count) _CONST_CALL_OPERATOR noexcept(_Choice<_It>._No_throw) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count >= 0, "The size passed to views::counted must be non-negative"); #endif constexpr _St _Strat = _Choice<_It>._Strategy; @@ -5669,7 +5669,7 @@ namespace ranges { constexpr explicit chunk_view(_Vw _Range_, const range_difference_t<_Vw> _Count_) noexcept(is_nothrow_move_constructible_v<_Vw>) /* strengthened */ : _Range(_STD move(_Range_)), _Count{_Count_} { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count > 0, "chunk size must be greater than 0"); #endif } @@ -5942,7 +5942,7 @@ namespace ranges { constexpr explicit chunk_view(_Vw _Range_, const range_difference_t<_Vw> _Count_) noexcept(is_nothrow_move_constructible_v<_Vw>) /* strengthened */ : _Range(_STD move(_Range_)), _Count{_Count_} { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count > 0, "chunk size must be greater than 0"); #endif } @@ -6319,7 +6319,7 @@ namespace ranges { constexpr explicit slide_view(_Vw _Range_, const range_difference_t<_Vw> _Count_) noexcept(is_nothrow_move_constructible_v<_Vw>) /* strengthened */ : _Range(_STD move(_Range_)), _Count{_Count_} { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count > 0, "The window size must be positive (N4950 [range.slide.view]/1)"); #endif } @@ -6595,14 +6595,14 @@ namespace ranges { } _NODISCARD constexpr const _Pr& pred() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "chunk_by_view has no predicate"); #endif return *_Pred; } _NODISCARD constexpr _Iterator begin() { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Pred, "cannot call begin on a chunk_by_view with no predicate"); #endif @@ -6927,7 +6927,7 @@ namespace ranges { constexpr explicit stride_view(_Vw _Range_, range_difference_t<_Vw> _Stride_) noexcept(is_nothrow_move_constructible_v<_Vw>) // strengthened : _Range(_STD move(_Range_)), _Stride(_Stride_) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Stride > 0, "stride must be greater than 0"); #endif } @@ -9153,7 +9153,7 @@ namespace ranges { requires _Cartesian_product_is_sized<_First, _Rest...> { return [&](index_sequence<_Indices...>) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 const array _Sizes = {static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases)))...}; const bool _Any_zero = ((_Sizes[_Indices] == 0) || ...); if (_Any_zero) { @@ -9165,9 +9165,9 @@ namespace ranges { _STL_VERIFY(!_Overflow, "Size of cartesian product cannot be represented by size type (N4950 " "[range.cartesian.view]/10)."); return _Product; -#else // ^^^ _CONTAINER_DEBUG_LEVEL > 0 / _CONTAINER_DEBUG_LEVEL == 0 vvv +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv return (static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases))) * ...); -#endif // ^^^ _CONTAINER_DEBUG_LEVEL == 0 ^^^ +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ }(make_index_sequence<1 + sizeof...(_Rest)>{}); } @@ -9175,7 +9175,7 @@ namespace ranges { requires _Cartesian_product_is_sized { return [&](index_sequence<_Indices...>) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 const array _Sizes = {static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases)))...}; const bool _Any_zero = ((_Sizes[_Indices] == 0) || ...); if (_Any_zero) { @@ -9187,9 +9187,9 @@ namespace ranges { _STL_VERIFY(!_Overflow, "Size of cartesian product cannot be represented by size type (N4950 " "[range.cartesian.view]/10)."); return _Product; -#else // ^^^ _CONTAINER_DEBUG_LEVEL > 0 / _CONTAINER_DEBUG_LEVEL == 0 vvv +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv return (static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases))) * ...); -#endif // ^^^ _CONTAINER_DEBUG_LEVEL == 0 ^^^ +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ }(make_index_sequence<1 + sizeof...(_Rest)>{}); } }; diff --git a/stl/inc/span b/stl/inc/span index 4f043ea279d..ec504c98775 100644 --- a/stl/inc/span +++ b/stl/inc/span @@ -206,7 +206,11 @@ struct _Span_extent_type { constexpr _Span_extent_type() noexcept = default; - constexpr explicit _Span_extent_type(const pointer _Data, size_t) noexcept : _Mydata{_Data} {} + constexpr explicit _Span_extent_type(const pointer _Data, size_t) noexcept : _Mydata{_Data} { + // Verify that later calls to size_bytes() won't overflow: + static_assert( + _Mysize <= dynamic_extent / sizeof(_Ty), "size of span in bytes exceeds numeric_limits::max()"); + } pointer _Mydata{nullptr}; static constexpr size_t _Mysize = _Extent; @@ -219,7 +223,13 @@ struct _Span_extent_type<_Ty, dynamic_extent> { constexpr _Span_extent_type() noexcept = default; constexpr explicit _Span_extent_type(const pointer _Data, const size_t _Size) noexcept - : _Mydata{_Data}, _Mysize{_Size} {} + : _Mydata{_Data}, _Mysize{_Size} { +#if _ITERATOR_DEBUG_LEVEL != 0 + // Verify that later calls to size_bytes() won't overflow: + _STL_VERIFY( + _Mysize <= dynamic_extent / sizeof(_Ty), "size of span in bytes exceeds numeric_limits::max()"); +#endif + } pointer _Mydata{nullptr}; size_t _Mysize{0}; @@ -294,12 +304,12 @@ public: template <_Span_compatible_iterator _It> constexpr explicit(_Extent != dynamic_extent) span(_It _First, size_type _Count) noexcept // strengthened : _Mybase(_STD to_address(_STD _Get_unwrapped_n(_First, _Count)), _Count) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Extent != dynamic_extent) { _STL_VERIFY(_Count == _Extent, "Cannot construct span with static extent from range [first, first + count) as count != extent"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 } template <_Span_compatible_iterator _It, _Span_compatible_sentinel<_It> _Sentinel> @@ -307,12 +317,12 @@ public: noexcept(noexcept(_Last - _First)) // strengthened : _Mybase(_STD to_address(_First), static_cast(_Last - _First)) { _STD _Adl_verify_range(_First, _Last); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Extent != dynamic_extent) { _STL_VERIFY(_Last - _First == _Extent, "Cannot construct span with static extent from range [first, last) as last - first != extent"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 } template @@ -331,12 +341,12 @@ public: template <_Span_compatible_range _Rng> constexpr explicit(_Extent != dynamic_extent) span(_Rng&& _Range) : _Mybase(_RANGES data(_Range), static_cast(_RANGES size(_Range))) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Extent != dynamic_extent) { _STL_VERIFY(_RANGES size(_Range) == _Extent, "Cannot construct span with static extent from range r as std::ranges::size(r) != extent"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 } template @@ -345,12 +355,12 @@ public: constexpr explicit(_Extent != dynamic_extent && _OtherExtent == dynamic_extent) span(const span<_OtherTy, _OtherExtent>& _Other) noexcept : _Mybase(_Other.data(), _Other.size()) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 if constexpr (_Extent != dynamic_extent) { _STL_VERIFY(_Other.size() == _Extent, "Cannot construct span with static extent from other span as other.size() != extent"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 } // [span.sub] Subviews @@ -359,18 +369,20 @@ public: if constexpr (_Extent != dynamic_extent) { static_assert(_Count <= _Extent, "Count out of range in span::first()"); } -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 else { _STL_VERIFY(_Count <= _Mysize, "Count out of range in span::first()"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 + return span{_Mydata, _Count}; } _NODISCARD constexpr auto first(const size_type _Count) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count <= _Mysize, "Count out of range in span::first(count)"); #endif + return span{_Mydata, _Count}; } @@ -379,18 +391,20 @@ public: if constexpr (_Extent != dynamic_extent) { static_assert(_Count <= _Extent, "Count out of range in span::last()"); } -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 else { _STL_VERIFY(_Count <= _Mysize, "Count out of range in span::last()"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 + return span{_Mydata + (_Mysize - _Count), _Count}; } _NODISCARD constexpr auto last(const size_type _Count) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Count <= _Mysize, "Count out of range in span::last(count)"); #endif + return span{_Mydata + (_Mysize - _Count), _Count}; } @@ -401,7 +415,7 @@ public: static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Count out of range in span::subspan()"); } -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 else { _STL_VERIFY(_Offset <= _Mysize, "Offset out of range in span::subspan()"); @@ -409,7 +423,8 @@ public: _STL_VERIFY(_Count <= _Mysize - _Offset, "Count out of range in span::subspan()"); } } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 + using _ReturnType = span; return _ReturnType{_Mydata + _Offset, _Count == dynamic_extent ? _Mysize - _Offset : _Count}; @@ -417,11 +432,12 @@ public: _NODISCARD constexpr auto subspan(const size_type _Offset, const size_type _Count = dynamic_extent) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Offset <= _Mysize, "Offset out of range in span::subspan(offset, count)"); _STL_VERIFY(_Count == dynamic_extent || _Count <= _Mysize - _Offset, "Count out of range in span::subspan(offset, count)"); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 + using _ReturnType = span; return _ReturnType{_Mydata + _Offset, _Count == dynamic_extent ? _Mysize - _Offset : _Count}; } @@ -431,16 +447,10 @@ public: return _Mysize; } -#pragma warning(push) -#pragma warning(disable : 4127) // conditional expression is constant _NODISCARD constexpr size_type size_bytes() const noexcept { -#if _CONTAINER_DEBUG_LEVEL > 0 - _STL_VERIFY(_Mysize <= dynamic_extent / sizeof(element_type), - "size of span in bytes exceeds std::numeric_limits::max()"); -#endif + // Under _ITERATOR_DEBUG_LEVEL != 0, span's constructors verify that this multiplication won't overflow. return _Mysize * sizeof(element_type); } -#pragma warning(pop) _NODISCARD constexpr bool empty() const noexcept { return _Mysize == 0; @@ -448,25 +458,28 @@ public: // [span.elem] Element access _NODISCARD constexpr reference operator[](const size_type _Off) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < _Mysize, "span subscript out of range"); #endif + return _Mydata[_Off]; } #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant _NODISCARD constexpr reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize > 0, "front() called on empty span"); #endif + return _Mydata[0]; } _NODISCARD constexpr reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_SPAN || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize > 0, "back() called on empty span"); #endif + return _Mydata[_Mysize - 1]; } #pragma warning(pop) diff --git a/stl/inc/valarray b/stl/inc/valarray index 5773a639e20..bb30c016487 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -290,7 +290,7 @@ public: } valarray& operator*=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -301,7 +301,7 @@ public: } valarray& operator/=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -312,7 +312,7 @@ public: } valarray& operator%=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -323,7 +323,7 @@ public: } valarray& operator+=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -334,7 +334,7 @@ public: } valarray& operator-=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -345,7 +345,7 @@ public: } valarray& operator^=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -356,7 +356,7 @@ public: } valarray& operator|=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -367,7 +367,7 @@ public: } valarray& operator&=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -378,7 +378,7 @@ public: } valarray& operator<<=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -389,7 +389,7 @@ public: } valarray& operator>>=(const valarray& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mysize == _Right._Mysize, "valarrays of different lengths"); #endif const size_t _Size = _Mysize; // eliminating indirection helps vectorization @@ -404,7 +404,7 @@ public: } _NODISCARD const _Ty& operator[](size_t _Off) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VALARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < _Mysize, "valarray subscript out of range"); #endif @@ -412,7 +412,7 @@ public: } _NODISCARD _Ty& operator[](size_t _Off) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VALARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < _Mysize, "valarray subscript out of range"); #endif @@ -866,7 +866,7 @@ _NODISCARD _Boolarray operator||(const typename valarray<_Ty>::value_type& _Left _EXPORT_STD template _NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -879,7 +879,7 @@ _NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator/(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -892,7 +892,7 @@ _NODISCARD valarray<_Ty> operator/(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator%(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -905,7 +905,7 @@ _NODISCARD valarray<_Ty> operator%(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator+(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -918,7 +918,7 @@ _NODISCARD valarray<_Ty> operator+(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator-(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -931,7 +931,7 @@ _NODISCARD valarray<_Ty> operator-(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator^(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -944,7 +944,7 @@ _NODISCARD valarray<_Ty> operator^(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator&(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -957,7 +957,7 @@ _NODISCARD valarray<_Ty> operator&(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator|(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -970,7 +970,7 @@ _NODISCARD valarray<_Ty> operator|(const valarray<_Ty>& _Left, const valarray<_T _EXPORT_STD template _NODISCARD valarray<_Ty> operator<<(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -983,7 +983,7 @@ _NODISCARD valarray<_Ty> operator<<(const valarray<_Ty>& _Left, const valarray<_ _EXPORT_STD template _NODISCARD valarray<_Ty> operator>>(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -996,7 +996,7 @@ _NODISCARD valarray<_Ty> operator>>(const valarray<_Ty>& _Left, const valarray<_ _EXPORT_STD template _NODISCARD _Boolarray operator&&(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1009,7 +1009,7 @@ _NODISCARD _Boolarray operator&&(const valarray<_Ty>& _Left, const valarray<_Ty> _EXPORT_STD template _NODISCARD _Boolarray operator||(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1042,7 +1042,7 @@ _NODISCARD _Boolarray operator==(const typename valarray<_Ty>::value_type& _Left _EXPORT_STD template _NODISCARD _Boolarray operator==(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1075,7 +1075,7 @@ _NODISCARD _Boolarray operator!=(const typename valarray<_Ty>::value_type& _Left _EXPORT_STD template _NODISCARD _Boolarray operator!=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1108,7 +1108,7 @@ _NODISCARD _Boolarray operator<(const typename valarray<_Ty>::value_type& _Left, _EXPORT_STD template _NODISCARD _Boolarray operator<(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1141,7 +1141,7 @@ _NODISCARD _Boolarray operator>(const typename valarray<_Ty>::value_type& _Left, _EXPORT_STD template _NODISCARD _Boolarray operator>(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1174,7 +1174,7 @@ _NODISCARD _Boolarray operator<=(const typename valarray<_Ty>::value_type& _Left _EXPORT_STD template _NODISCARD _Boolarray operator<=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); @@ -1207,7 +1207,7 @@ _NODISCARD _Boolarray operator>=(const typename valarray<_Ty>::value_type& _Left _EXPORT_STD template _NODISCARD _Boolarray operator>=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Left.size() == _Right.size(), "valarrays of different lengths"); #endif const size_t _Size = _Left.size(); diff --git a/stl/inc/vector b/stl/inc/vector index ae8330bf2d2..1450120f061 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -1736,7 +1736,7 @@ public: auto& _My_data = _Mypair._Myval2; pointer& _Mylast = _My_data._Mylast; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _Mylast, "pop_back() called on empty vector"); #endif @@ -1913,7 +1913,7 @@ public: _NODISCARD _CONSTEXPR20 _Ty& operator[](const size_type _Pos) noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY( _Pos < static_cast(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range"); #endif @@ -1923,7 +1923,7 @@ public: _NODISCARD _CONSTEXPR20 const _Ty& operator[](const size_type _Pos) const noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY( _Pos < static_cast(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range"); #endif @@ -1951,7 +1951,7 @@ public: _NODISCARD _CONSTEXPR20 _Ty& front() noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "front() called on empty vector"); #endif @@ -1960,7 +1960,7 @@ public: _NODISCARD _CONSTEXPR20 const _Ty& front() const noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "front() called on empty vector"); #endif @@ -1969,7 +1969,7 @@ public: _NODISCARD _CONSTEXPR20 _Ty& back() noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "back() called on empty vector"); #endif @@ -1978,7 +1978,7 @@ public: _NODISCARD _CONSTEXPR20 const _Ty& back() const noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "back() called on empty vector"); #endif @@ -3209,7 +3209,7 @@ public: } _NODISCARD _CONSTEXPR20 const_reference operator[](size_type _Off) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < this->_Mysize, "vector subscript out of range"); #endif @@ -3219,7 +3219,7 @@ public: } _NODISCARD _CONSTEXPR20 reference operator[](size_type _Off) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < this->_Mysize, "vector subscript out of range"); #endif @@ -3229,7 +3229,7 @@ public: } _NODISCARD _CONSTEXPR20 reference front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Mysize != 0, "front() called on empty vector"); #endif @@ -3237,7 +3237,7 @@ public: } _NODISCARD _CONSTEXPR20 const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Mysize != 0, "front() called on empty vector"); #endif @@ -3245,7 +3245,7 @@ public: } _NODISCARD _CONSTEXPR20 reference back() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Mysize != 0, "back() called on empty vector"); #endif @@ -3253,7 +3253,7 @@ public: } _NODISCARD _CONSTEXPR20 const_reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(this->_Mysize != 0, "back() called on empty vector"); #endif @@ -3272,6 +3272,10 @@ public: #endif // _HAS_CXX23 _CONSTEXPR20 void pop_back() noexcept /* strengthened */ { +#if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(this->_Mysize != 0, "pop_back() called on empty vector"); +#endif + erase(end() - 1); } diff --git a/stl/inc/xstring b/stl/inc/xstring index e18772035bf..6763eecdb26 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -2246,17 +2246,19 @@ public: } _NODISCARD _CONSTEXPR20 reference operator[](const size_type _Off) noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off <= _Mypair._Myval2._Mysize, "string subscript out of range"); #endif + return _Mypair._Myval2._Myptr()[_Off]; } _NODISCARD _CONSTEXPR20 const_reference operator[](const size_type _Off) const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off <= _Mypair._Myval2._Mysize, "string subscript out of range"); #endif + return _Mypair._Myval2._Myptr()[_Off]; } @@ -2291,14 +2293,16 @@ public: _CONSTEXPR20 void pop_back() noexcept /* strengthened */ { const size_type _Old_size = _Mypair._Myval2._Mysize; -#if _ITERATOR_DEBUG_LEVEL >= 1 + +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Old_size != 0, "pop_back() called on empty string"); -#endif // _ITERATOR_DEBUG_LEVEL >= 1 +#endif + _Eos(_Old_size - 1); } _NODISCARD _CONSTEXPR20 reference front() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "front() called on empty string"); #endif @@ -2306,7 +2310,7 @@ public: } _NODISCARD _CONSTEXPR20 const_reference front() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "front() called on empty string"); #endif @@ -2314,7 +2318,7 @@ public: } _NODISCARD _CONSTEXPR20 reference back() noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "back() called on empty string"); #endif @@ -2322,7 +2326,7 @@ public: } _NODISCARD _CONSTEXPR20 const_reference back() const noexcept /* strengthened */ { -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _MSVC_STL_HARDENING_BASIC_STRING || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mypair._Myval2._Mysize != 0, "back() called on empty string"); #endif @@ -2391,10 +2395,10 @@ public: auto _Arg_size = _New_size; const auto _Result_size = _STD move(_Op)(_Arg_ptr, _Arg_size); const auto _Result_as_size_type = static_cast(_Result_size); -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Result_size >= 0, "the returned size can't be smaller than 0"); _STL_VERIFY(_Result_as_size_type <= _New_size, "the returned size can't be greater than the passed size"); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 _Eos(_Result_as_size_type); } diff --git a/stl/inc/xutility b/stl/inc/xutility index 0c5c942a29d..cd3abe887b1 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -3823,9 +3823,11 @@ namespace ranges { requires forward_range<_Derived> { auto& _Self = _Cast(); -#if _CONTAINER_DEBUG_LEVEL > 0 + +#if _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_RANGES empty(_Self), "front() called on empty ranges::view_interface"); #endif + return *_RANGES begin(_Self); } @@ -3833,9 +3835,11 @@ namespace ranges { requires forward_range { auto& _Self = _Cast(); -#if _CONTAINER_DEBUG_LEVEL > 0 + +#if _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_RANGES empty(_Self), "front() called on empty ranges::view_interface"); #endif + return *_RANGES begin(_Self); } @@ -3843,9 +3847,11 @@ namespace ranges { requires bidirectional_range<_Derived> && common_range<_Derived> { auto& _Self = _Cast(); -#if _CONTAINER_DEBUG_LEVEL > 0 + +#if _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_RANGES empty(_Self), "back() called on empty ranges::view_interface"); #endif + auto _Last = _RANGES end(_Self); return *--_Last; } @@ -3854,9 +3860,11 @@ namespace ranges { requires bidirectional_range && common_range { auto& _Self = _Cast(); -#if _CONTAINER_DEBUG_LEVEL > 0 + +#if _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(!_RANGES empty(_Self), "back() called on empty ranges::view_interface"); #endif + auto _Last = _RANGES end(_Self); return *--_Last; } @@ -3864,26 +3872,30 @@ namespace ranges { template _NODISCARD constexpr decltype(auto) operator[](const range_difference_t<_Rng> _Idx) { auto& _Self = _Cast(); -#if _CONTAINER_DEBUG_LEVEL > 0 + +#if _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 if constexpr (sized_range<_Derived>) { using _U_diff = _Make_unsigned_like_t>; _STL_VERIFY(static_cast<_U_diff>(_Idx) < static_cast<_U_diff>(_RANGES size(_Self)), "ranges::view_interface subscript out of range"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 + return _RANGES begin(_Self)[_Idx]; } template _NODISCARD constexpr decltype(auto) operator[](const range_difference_t<_Rng> _Idx) const { auto& _Self = _Cast(); -#if _CONTAINER_DEBUG_LEVEL > 0 + +#if _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 if constexpr (sized_range<_Derived>) { using _U_diff = _Make_unsigned_like_t>; _STL_VERIFY(static_cast<_U_diff>(_Idx) < static_cast<_U_diff>(_RANGES size(_Self)), "ranges::view_interface subscript out of range"); } -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE || _ITERATOR_DEBUG_LEVEL != 0 + return _RANGES begin(_Self)[_Idx]; } }; diff --git a/stl/inc/yvals.h b/stl/inc/yvals.h index 5922af50231..bae84f1e6b1 100644 --- a/stl/inc/yvals.h +++ b/stl/inc/yvals.h @@ -157,33 +157,102 @@ _STL_DISABLE_CLANG_WARNINGS #endif // defined(_DLL) etc. #endif // !defined(_ALLOW_RUNTIME_LIBRARY_MISMATCH) -#ifndef _CONTAINER_DEBUG_LEVEL -#if _ITERATOR_DEBUG_LEVEL == 0 -#define _CONTAINER_DEBUG_LEVEL 0 -#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 / _ITERATOR_DEBUG_LEVEL != 0 vvv -#define _CONTAINER_DEBUG_LEVEL 1 -#endif // _ITERATOR_DEBUG_LEVEL == 0 -#endif // !defined(_CONTAINER_DEBUG_LEVEL) - -#if _ITERATOR_DEBUG_LEVEL != 0 && _CONTAINER_DEBUG_LEVEL == 0 -#error _ITERATOR_DEBUG_LEVEL != 0 must imply _CONTAINER_DEBUG_LEVEL == 1. -#endif // _ITERATOR_DEBUG_LEVEL != 0 && _CONTAINER_DEBUG_LEVEL == 0 - -#ifndef _STL_CRT_SECURE_INVALID_PARAMETER +#ifdef _CONTAINER_DEBUG_LEVEL +_EMIT_STL_ERROR(STL1006, "_CONTAINER_DEBUG_LEVEL has been removed. It was superseded by _MSVC_STL_HARDENING."); +#endif + +#ifndef _MSVC_STL_HARDENING +#define _MSVC_STL_HARDENING 0 +#endif + +#ifndef _MSVC_STL_HARDENING_ARRAY +#define _MSVC_STL_HARDENING_ARRAY _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_BASIC_STRING +#define _MSVC_STL_HARDENING_BASIC_STRING _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_BASIC_STRING_VIEW +#define _MSVC_STL_HARDENING_BASIC_STRING_VIEW _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_BITSET +#define _MSVC_STL_HARDENING_BITSET _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_DEQUE +#define _MSVC_STL_HARDENING_DEQUE _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_EXPECTED +#define _MSVC_STL_HARDENING_EXPECTED _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_FORWARD_LIST +#define _MSVC_STL_HARDENING_FORWARD_LIST _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_LIST +#define _MSVC_STL_HARDENING_LIST _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_MDSPAN +#define _MSVC_STL_HARDENING_MDSPAN _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_OPTIONAL +#define _MSVC_STL_HARDENING_OPTIONAL _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE +#define _MSVC_STL_HARDENING_RANGES_VIEW_INTERFACE _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_SPAN +#define _MSVC_STL_HARDENING_SPAN _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_VALARRAY +#define _MSVC_STL_HARDENING_VALARRAY _MSVC_STL_HARDENING +#endif + +#ifndef _MSVC_STL_HARDENING_VECTOR +#define _MSVC_STL_HARDENING_VECTOR _MSVC_STL_HARDENING +#endif + +#ifdef _STL_CRT_SECURE_INVALID_PARAMETER +_EMIT_STL_ERROR(STL1007, "_STL_CRT_SECURE_INVALID_PARAMETER has been removed. " + "It was superseded by _MSVC_STL_DOOM_FUNCTION."); +#endif + #ifdef _STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER -#define _STL_CRT_SECURE_INVALID_PARAMETER(expr) _CSTD abort() -#elif defined(_DEBUG) // Avoid emitting unused long strings for function names; see GH-1956. -// static_cast(__LINE__) avoids warning C4365 (signed/unsigned mismatch) with the /ZI compiler option. -#define _STL_CRT_SECURE_INVALID_PARAMETER(expr) \ - ::_invalid_parameter(_CRT_WIDE(#expr), L"", __FILEW__, static_cast(__LINE__), 0) -#else // ^^^ defined(_DEBUG) / !defined(_DEBUG) vvv -#define _STL_CRT_SECURE_INVALID_PARAMETER(expr) _CRT_SECURE_INVALID_PARAMETER(expr) -#endif // ^^^ !defined(_DEBUG) ^^^ -#endif // !defined(_STL_CRT_SECURE_INVALID_PARAMETER) +_EMIT_STL_ERROR(STL1008, "_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER has been removed. " + "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 +#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). +#define _MSVC_STL_DOOM_FUNCTION(mesg) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0) +#endif // ^^^ !defined(_MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION) ^^^ +#endif // ^^^ !defined(_MSVC_STL_DOOM_FUNCTION) ^^^ #define _STL_REPORT_ERROR(mesg) \ _RPTF0(_CRT_ASSERT, mesg); \ - _STL_CRT_SECURE_INVALID_PARAMETER(mesg) + _MSVC_STL_DOOM_FUNCTION(mesg) #define _STL_VERIFY(cond, mesg) \ if (!(cond)) { \ @@ -417,7 +486,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) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0) #define _RERAISE #define _THROW(...) (__VA_ARGS__)._Raise() diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 2bd67b707b9..4adc435e9b6 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1519,7 +1519,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect // next warning number: STL4049 -// next error number: STL1006 +// next error number: STL1009 // P0619R4 Removing C++17-Deprecated Features #ifndef _HAS_FEATURES_REMOVED_IN_CXX20 diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 52c4877f626..8c55f59e92d 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -996,10 +996,12 @@ std/containers/sequences/vector/vector.modifiers/destroy_elements.pass.cpp FAIL std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp FAIL std/strings/basic.string/string.modifiers/string_replace/replace_with_range.pass.cpp FAIL std/utilities/charconv/charconv.to.chars/integral.pass.cpp FAIL -std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp FAIL -std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp FAIL -std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp FAIL -std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp FAIL + +# Not analyzed, failing due to constexpr step limits. SKIPPED because they occasionally pass in certain configurations. +std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp SKIPPED +std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp SKIPPED +std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp SKIPPED +std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp SKIPPED # Not analyzed. In debug mode, looks like a proxy object unexpectedly exhausts an 80-byte buffer. # In release mode, fails in a later assertion that appears to be testing libc++-specific behavior. diff --git a/tests/libcxx/usual_matrix.lst b/tests/libcxx/usual_matrix.lst index a6642320f3a..72969ef33cc 100644 --- a/tests/libcxx/usual_matrix.lst +++ b/tests/libcxx/usual_matrix.lst @@ -3,7 +3,7 @@ RUNALL_INCLUDE ..\universal_prefix.lst RUNALL_CROSSLIST -* PM_CL="/EHsc /MTd /std:c++latest /permissive- /utf-8 /FImsvc_stdlib_force_include.h /wd4643 /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER" +* PM_CL="/EHsc /MTd /std:c++latest /permissive- /utf-8 /FImsvc_stdlib_force_include.h /wd4643" RUNALL_CROSSLIST PM_CL="/analyze:autolog- /Zc:preprocessor /wd6262" ASAN PM_CL="-fsanitize=address /Zi" PM_LINK="/debug" diff --git a/tests/std/test.lst b/tests/std/test.lst index 7093936102a..e188823bfcf 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -253,6 +253,7 @@ tests\GH_004657_expected_constraints_permissive tests\GH_004845_logical_operator_traits_with_non_bool_constant tests\GH_004929_internal_tag_constructors tests\GH_004930_char_traits_user_specialization +tests\GH_005090_stl_hardening tests\LWG2381_num_get_floating_point tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function diff --git a/tests/std/tests/GH_005090_stl_hardening/env.lst b/tests/std/tests/GH_005090_stl_hardening/env.lst new file mode 100644 index 00000000000..606d5f84175 --- /dev/null +++ b/tests/std/tests/GH_005090_stl_hardening/env.lst @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst +RUNALL_CROSSLIST +* PM_CL="/D_MSVC_STL_HARDENING=1" diff --git a/tests/std/tests/GH_005090_stl_hardening/test.cpp b/tests/std/tests/GH_005090_stl_hardening/test.cpp new file mode 100644 index 00000000000..9fc8b475a9c --- /dev/null +++ b/tests/std/tests/GH_005090_stl_hardening/test.cpp @@ -0,0 +1,711 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// env.lst defines _MSVC_STL_HARDENING to 1. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if _HAS_CXX17 +#include +#include +#endif // _HAS_CXX17 + +#if _HAS_CXX20 +#include +#include +#endif // _HAS_CXX20 + +#if _HAS_CXX23 +#include +#include +#endif // _HAS_CXX23 + +#include + +using namespace std; + +// +void test_array_subscript() { + array a{}; +#pragma warning(push) +#pragma warning(disable : 28020) // /analyze correctly warns: The expression '_Param_(1)<3' is not true at this call. + (void) a[3]; +#pragma warning(pop) +} + +void test_array_subscript_const() { + const array a{}; +#pragma warning(push) +#pragma warning(disable : 28020) // /analyze correctly warns: The expression '_Param_(1)<3' is not true at this call. + (void) a[3]; +#pragma warning(pop) +} + +void test_array_zero_subscript() { + array az{}; + (void) az[0]; +} + +void test_array_zero_subscript_const() { + const array az{}; + (void) az[0]; +} + +void test_array_zero_front() { + array az{}; + (void) az.front(); +} + +void test_array_zero_front_const() { + const array az{}; + (void) az.front(); +} + +void test_array_zero_back() { + array az{}; + (void) az.back(); +} + +void test_array_zero_back_const() { + const array az{}; + (void) az.back(); +} + +// +void test_bitset_subscript() { + bitset<100> b{}; + (void) b[100]; +} + +void test_bitset_subscript_const() { + const bitset<100> b{}; + (void) b[100]; +} + +// +void test_deque_subscript() { + deque d(3); + (void) d[3]; +} + +void test_deque_subscript_const() { + const deque d(3); + (void) d[3]; +} + +void test_deque_front() { + deque d{}; + (void) d.front(); +} + +void test_deque_front_const() { + const deque d{}; + (void) d.front(); +} + +void test_deque_back() { + deque d{}; + (void) d.back(); +} + +void test_deque_back_const() { + const deque d{}; + (void) d.back(); +} + +void test_deque_pop_front() { + deque d{}; + d.pop_front(); +} + +void test_deque_pop_back() { + deque d{}; + d.pop_back(); +} + +// +void test_forward_list_front() { + forward_list fl{}; + (void) fl.front(); +} + +void test_forward_list_front_const() { + const forward_list fl{}; + (void) fl.front(); +} + +void test_forward_list_pop_front() { + forward_list fl{}; + fl.pop_front(); +} + +// +void test_list_front() { + list l{}; + (void) l.front(); +} + +void test_list_front_const() { + const list l{}; + (void) l.front(); +} + +void test_list_back() { + list l{}; + (void) l.back(); +} + +void test_list_back_const() { + const list l{}; + (void) l.back(); +} + +void test_list_pop_front() { + list l{}; + l.pop_front(); +} + +void test_list_pop_back() { + list l{}; + l.pop_back(); +} + +// +void test_string_subscript() { + string s(3, '*'); + (void) s[4]; // beyond null terminator +} + +void test_string_subscript_const() { + const string s(3, '*'); + (void) s[4]; // beyond null terminator +} + +void test_string_front() { + string s{}; + (void) s.front(); +} + +void test_string_front_const() { + const string s{}; + (void) s.front(); +} + +void test_string_back() { + string s{}; + (void) s.back(); +} + +void test_string_back_const() { + const string s{}; + (void) s.back(); +} + +void test_string_pop_back() { + string s{}; + s.pop_back(); +} + +// +void test_valarray_subscript() { + valarray va(3); + (void) va[3]; +} + +void test_valarray_subscript_const() { + const valarray va(3); + (void) va[3]; +} + +// +void test_vector_subscript() { + vector v(3); + (void) v[3]; +} + +void test_vector_subscript_const() { + const vector v(3); + (void) v[3]; +} + +void test_vector_front() { + vector v{}; + (void) v.front(); +} + +void test_vector_front_const() { + const vector v{}; + (void) v.front(); +} + +void test_vector_back() { + vector v{}; + (void) v.back(); +} + +void test_vector_back_const() { + const vector v{}; + (void) v.back(); +} + +void test_vector_pop_back() { + vector v{}; + v.pop_back(); +} + +void test_vector_bool_subscript() { + vector vb(3); + (void) vb[3]; +} + +void test_vector_bool_subscript_const() { + const vector vb(3); + (void) vb[3]; +} + +void test_vector_bool_front() { + vector vb{}; + (void) vb.front(); +} + +void test_vector_bool_front_const() { + const vector vb{}; + (void) vb.front(); +} + +void test_vector_bool_back() { + vector vb{}; + (void) vb.back(); +} + +void test_vector_bool_back_const() { + const vector vb{}; + (void) vb.back(); +} + +void test_vector_bool_pop_back() { + vector vb{}; + vb.pop_back(); +} + +#if _HAS_CXX17 +// +void test_optional_deref_lvalue() { + optional o{}; + (void) *o; +} + +void test_optional_deref_lvalue_const() { + const optional o{}; + (void) *o; +} + +void test_optional_deref_rvalue() { + optional o{}; + (void) *move(o); +} + +void test_optional_deref_rvalue_const() { + const optional o{}; + (void) *move(o); +} + +void test_optional_arrow() { + optional o{}; + (void) o.operator->(); +} + +void test_optional_arrow_const() { + const optional o{}; + (void) o.operator->(); +} + +// +void test_string_view_subscript() { + const string_view sv{"Toki"}; + (void) sv[4]; +} + +void test_string_view_front() { + const string_view sv{}; + (void) sv.front(); +} + +void test_string_view_back() { + const string_view sv{}; + (void) sv.back(); +} + +void test_string_view_remove_prefix() { + string_view sv{"Cosmos"}; + sv.remove_prefix(7); +} + +void test_string_view_remove_suffix() { + string_view sv{"Meadow"}; + sv.remove_suffix(7); +} +#endif // _HAS_CXX17 + +#if _HAS_CXX20 +// +// ranges::subrange derives from ranges::view_interface, which is hardened. +void test_ranges_view_interface_subscript() { + int arr[10]{}; + ranges::subrange sr{arr + 5, arr + 8}; + (void) sr[3]; +} + +void test_ranges_view_interface_subscript_const() { + int arr[10]{}; + const ranges::subrange sr{arr + 5, arr + 8}; + (void) sr[3]; +} + +void test_ranges_view_interface_front() { + int arr[10]{}; + ranges::subrange sr{arr + 5, arr + 5}; + (void) sr.front(); +} + +void test_ranges_view_interface_front_const() { + int arr[10]{}; + const ranges::subrange sr{arr + 5, arr + 5}; + (void) sr.front(); +} + +void test_ranges_view_interface_back() { + int arr[10]{}; + ranges::subrange sr{arr + 5, arr + 5}; + (void) sr.back(); +} + +void test_ranges_view_interface_back_const() { + int arr[10]{}; + const ranges::subrange sr{arr + 5, arr + 5}; + (void) sr.back(); +} + +// +void test_span_ctor_first_count() { + int arr[10]{}; + span sp_static{arr, 10}; +} + +void test_span_ctor_first_last() { + int arr[10]{}; + span sp_static{arr, arr + 10}; +} + +void test_span_ctor_range() { + vector v(10); + span sp_static{v}; +} + +void test_span_ctor_other() { + int arr[10]{}; + span other{arr}; + span sp_static{other}; +} + +void test_span_first_compiletime() { + int arr[10]{}; + const span sp{arr}; + (void) sp.first<11>(); +} + +void test_span_first_runtime() { + int arr[10]{}; + const span sp{arr}; + (void) sp.first(11); +} + +void test_span_last_compiletime() { + int arr[10]{}; + const span sp{arr}; + (void) sp.last<11>(); +} + +void test_span_last_runtime() { + int arr[10]{}; + const span sp{arr}; + (void) sp.last(11); +} + +void test_span_subspan_compiletime_bad_offset() { + int arr[10]{}; + const span sp{arr}; + (void) sp.subspan<11>(); +} + +void test_span_subspan_compiletime_bad_count() { + int arr[10]{}; + const span sp{arr}; + (void) sp.subspan<3, 8>(); +} + +void test_span_subspan_runtime_bad_offset() { + int arr[10]{}; + const span sp{arr}; + (void) sp.subspan(11); +} + +void test_span_subspan_runtime_bad_count() { + int arr[10]{}; + const span sp{arr}; + (void) sp.subspan(3, 8); +} + +void test_span_subscript() { + int arr[10]{}; + const span sp{arr}; + (void) sp[10]; +} + +void test_span_front() { + const span sp{}; + (void) sp.front(); +} + +void test_span_back() { + const span sp{}; + (void) sp.back(); +} +#endif // _HAS_CXX20 + +#if _HAS_CXX23 +// +void test_expected_arrow() { + expected e{unexpect, "woof"}; + (void) e.operator->(); +} + +void test_expected_arrow_const() { + const expected e{unexpect, "woof"}; + (void) e.operator->(); +} + +void test_expected_deref_lvalue() { + expected e{unexpect, "woof"}; + (void) *e; +} + +void test_expected_deref_lvalue_const() { + const expected e{unexpect, "woof"}; + (void) *e; +} + +void test_expected_deref_rvalue() { + expected e{unexpect, "woof"}; + (void) *move(e); +} + +void test_expected_deref_rvalue_const() { + const expected e{unexpect, "woof"}; + (void) *move(e); +} + +void test_expected_error_lvalue() { + expected e{1729}; + (void) e.error(); +} + +void test_expected_error_lvalue_const() { + const expected e{1729}; + (void) e.error(); +} + +void test_expected_error_rvalue() { + expected e{1729}; + (void) move(e).error(); +} + +void test_expected_error_rvalue_const() { + const expected e{1729}; + (void) move(e).error(); +} + +void test_expected_void_deref() { + const expected ev{unexpect, "woof"}; + (void) *ev; +} + +void test_expected_void_error_lvalue() { + expected ev{}; + (void) ev.error(); +} + +void test_expected_void_error_lvalue_const() { + const expected ev{}; + (void) ev.error(); +} + +void test_expected_void_error_rvalue() { + expected ev{}; + (void) move(ev).error(); +} + +void test_expected_void_error_rvalue_const() { + const expected ev{}; + (void) move(ev).error(); +} + +// +void test_mdspan_ctor_other() { + char arr[12]{}; + mdspan> other{arr, 4, 3}; + mdspan> md{other}; +} + +#ifdef __cpp_multidimensional_subscript // TRANSITION, P2128R6 +void test_mdspan_subscript_multidim() { + const auto str{"HissMeowPurr"}; + const mdspan> md{str, 3, 4}; + (void) md[1, 4]; +} +#endif // ^^^ defined(__cpp_multidimensional_subscript) ^^^ + +void test_mdspan_subscript_array() { + const auto str{"HissMeowPurr"}; + const mdspan> md{str, 3, 4}; + const array a_idx{1, 4}; + (void) md[a_idx]; +} + +void test_mdspan_subscript_span() { + const auto str{"HissMeowPurr"}; + const mdspan> md{str, 3, 4}; + const array a_idx{1, 4}; + const span sp_idx{a_idx}; + (void) md[sp_idx]; +} +#endif // _HAS_CXX23 + +int main(int argc, char* argv[]) { + std_testing::death_test_executive exec; + + exec.add_death_tests({ + test_array_subscript, + test_array_subscript_const, + test_array_zero_subscript, + test_array_zero_subscript_const, + test_array_zero_front, + test_array_zero_front_const, + test_array_zero_back, + test_array_zero_back_const, + test_bitset_subscript, + test_bitset_subscript_const, + test_deque_subscript, + test_deque_subscript_const, + test_deque_front, + test_deque_front_const, + test_deque_back, + test_deque_back_const, + test_deque_pop_front, + test_deque_pop_back, + test_forward_list_front, + test_forward_list_front_const, + test_forward_list_pop_front, + test_list_front, + test_list_front_const, + test_list_back, + test_list_back_const, + test_list_pop_front, + test_list_pop_back, + test_string_subscript, + test_string_subscript_const, + test_string_front, + test_string_front_const, + test_string_back, + test_string_back_const, + test_string_pop_back, + test_valarray_subscript, + test_valarray_subscript_const, + test_vector_subscript, + test_vector_subscript_const, + test_vector_front, + test_vector_front_const, + test_vector_back, + test_vector_back_const, + test_vector_pop_back, + test_vector_bool_subscript, + test_vector_bool_subscript_const, + test_vector_bool_front, + test_vector_bool_front_const, + test_vector_bool_back, + test_vector_bool_back_const, + test_vector_bool_pop_back, + +#if _HAS_CXX17 + test_optional_deref_lvalue, + test_optional_deref_lvalue_const, + test_optional_deref_rvalue, + test_optional_deref_rvalue_const, + test_optional_arrow, + test_optional_arrow_const, + test_string_view_subscript, + test_string_view_front, + test_string_view_back, + test_string_view_remove_prefix, + test_string_view_remove_suffix, +#endif // _HAS_CXX17 + +#if _HAS_CXX20 + test_ranges_view_interface_subscript, + test_ranges_view_interface_subscript_const, + test_ranges_view_interface_front, + test_ranges_view_interface_front_const, + test_ranges_view_interface_back, + test_ranges_view_interface_back_const, + test_span_ctor_first_count, + test_span_ctor_first_last, + test_span_ctor_range, + test_span_ctor_other, + test_span_first_compiletime, + test_span_first_runtime, + test_span_last_compiletime, + test_span_last_runtime, + test_span_subspan_compiletime_bad_offset, + test_span_subspan_compiletime_bad_count, + test_span_subspan_runtime_bad_offset, + test_span_subspan_runtime_bad_count, + test_span_subscript, + test_span_front, + test_span_back, +#endif // _HAS_CXX20 + +#if _HAS_CXX23 + test_expected_arrow, + test_expected_arrow_const, + test_expected_deref_lvalue, + test_expected_deref_lvalue_const, + test_expected_deref_rvalue, + test_expected_deref_rvalue_const, + test_expected_error_lvalue, + test_expected_error_lvalue_const, + test_expected_error_rvalue, + test_expected_error_rvalue_const, + test_expected_void_deref, + test_expected_void_error_lvalue, + test_expected_void_error_lvalue_const, + test_expected_void_error_rvalue, + test_expected_void_error_rvalue_const, + test_mdspan_ctor_other, +#ifdef __cpp_multidimensional_subscript // TRANSITION, P2128R6 + test_mdspan_subscript_multidim, +#endif // ^^^ defined(__cpp_multidimensional_subscript) ^^^ + test_mdspan_subscript_array, + test_mdspan_subscript_span, +#endif // _HAS_CXX23 + }); + + return exec.run(argc, argv); +} diff --git a/tests/std/tests/P0009R18_mdspan_extents_death/test.cpp b/tests/std/tests/P0009R18_mdspan_extents_death/test.cpp index bdb9279c6af..2ef5d3fc05e 100644 --- a/tests/std/tests/P0009R18_mdspan_extents_death/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_extents_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -97,6 +95,8 @@ void test_construction_from_array_with_unrepresentable_as_index_type_values() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; + +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_static_extent_function_with_invalid_index, test_extent_function_with_invalid_index, @@ -111,5 +111,7 @@ int main(int argc, char* argv[]) { test_construction_from_array_with_invalid_values, test_construction_from_array_with_unrepresentable_as_index_type_values, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 + return exec.run(argc, argv); } diff --git a/tests/std/tests/P0009R18_mdspan_layout_left_death/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_left_death/test.cpp index b0b5f031e7d..ce0fb911717 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_left_death/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_left_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -41,7 +39,7 @@ void test_construction_from_other_stride_mapping_1() { layout_stride::mapping m1{Ext{}, array{4, 1}}; // For all r in the range [0, extents_type::rank()), other.stride(r) must be equal to // extents().fwd-prod-of-extents(r) - layout_left::mapping m2{m1}; + [[maybe_unused]] layout_left::mapping m2{m1}; } void test_construction_from_other_stride_mapping_2() { @@ -67,6 +65,8 @@ void test_stride_function() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; + +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_construction_from_extents_type_with_signed_index_type, test_construction_from_extents_type_with_unsigned_index_type, @@ -77,5 +77,7 @@ int main(int argc, char* argv[]) { test_call_operator, test_stride_function, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 + return exec.run(argc, argv); } diff --git a/tests/std/tests/P0009R18_mdspan_layout_right_death/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_right_death/test.cpp index ef72ed7be34..4de267099f8 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_right_death/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_right_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -41,7 +39,7 @@ void test_construction_from_other_stride_mapping_1() { layout_stride::mapping m1{Ext{}, array{1, 2}}; // For all r in the range [0, extents_type::rank()), other.stride(r) must be equal to // extents().rev-prod-of-extents(r) - layout_right::mapping m2{m1}; + [[maybe_unused]] layout_right::mapping m2{m1}; } void test_construction_from_other_stride_mapping_2() { @@ -67,6 +65,8 @@ void test_stride_function() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; + +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_construction_from_extents_type_with_signed_index_type, test_construction_from_extents_type_with_unsigned_index_type, @@ -77,5 +77,7 @@ int main(int argc, char* argv[]) { test_call_operator, test_stride_function, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 + return exec.run(argc, argv); } diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride_death/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride_death/test.cpp index 4668facbd22..2c1cb19e7df 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride_death/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -69,6 +67,8 @@ void test_stride_with_empty_extents() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; + +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_default_construction, test_construction_from_extents_and_array_1, @@ -79,5 +79,7 @@ int main(int argc, char* argv[]) { test_call_operator, test_stride_with_empty_extents, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 + return exec.run(argc, argv); } diff --git a/tests/std/tests/P0009R18_mdspan_mdspan_death/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan_death/test.cpp index e1c3bba1a91..2e225ae4fa2 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan_death/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -57,6 +55,8 @@ void test_size_when_index_type_is_unsigned() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; + +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_construction_from_other_mdspan, #ifdef __cpp_multidimensional_subscript // TRANSITION, P2128R6 @@ -68,5 +68,7 @@ int main(int argc, char* argv[]) { test_size_when_index_type_is_signed, test_size_when_index_type_is_unsigned, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 + return exec.run(argc, argv); } diff --git a/tests/std/tests/P0122R7_span_death/test.cpp b/tests/std/tests/P0122R7_span_death/test.cpp index 545b6729dec..48baa31a2f7 100644 --- a/tests/std/tests/P0122R7_span_death/test.cpp +++ b/tests/std/tests/P0122R7_span_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -261,7 +259,7 @@ void test_case_subspan_excessive_runtime_count_static_extent() { } void test_case_size_bytes_overflow() { - span sp(begin(globalArray), static_cast(-2)); // undefined behavior, not detected here + span sp(begin(globalArray), static_cast(-2)); // undefined behavior is detected here (void) sp.size_bytes(); // size of span in bytes exceeds std::numeric_limits::max() } @@ -330,11 +328,6 @@ int main(int argc, char* argv[]) { test_case_algorithm_incompatible_different_size, test_case_algorithm_incompatible_value_initialized, test_case_algorithm_incompatible_transposed, - }); -#endif // _ITERATOR_DEBUG_LEVEL != 0 - - // _CONTAINER_DEBUG_LEVEL tests - exec.add_death_tests({ test_case_constructor_first_count_incompatible_extent, test_case_constructor_first_last_incompatible_extent, test_case_constructor_range_incompatible_extent, @@ -359,6 +352,7 @@ int main(int argc, char* argv[]) { test_case_front_empty_static_extent, test_case_back_empty_static_extent, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0220R1_optional_death/test.cpp b/tests/std/tests/P0220R1_optional_death/test.cpp index bdc284f0028..b55a59b2928 100644 --- a/tests/std/tests/P0220R1_optional_death/test.cpp +++ b/tests/std/tests/P0220R1_optional_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -47,6 +45,7 @@ void test_nullopt_operator_star_const_rvalue() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_nullopt_operator_arrow, test_nullopt_operator_arrow_const, @@ -55,6 +54,7 @@ int main(int argc, char* argv[]) { test_nullopt_operator_star_rvalue, test_nullopt_operator_star_const_rvalue, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index 37476de98b0..ce2eccd161b 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include diff --git a/tests/std/tests/P0896R4_views_counted_death/test.cpp b/tests/std/tests/P0896R4_views_counted_death/test.cpp index 1ec2d648cd4..8bb5fdba4b7 100644 --- a/tests/std/tests/P0896R4_views_counted_death/test.cpp +++ b/tests/std/tests/P0896R4_views_counted_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -17,11 +15,11 @@ void test_constructor_negative_size() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; -#ifdef _DEBUG +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_constructor_negative_size, }); -#endif // _DEBUG +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0896R4_views_drop_death/test.cpp b/tests/std/tests/P0896R4_views_drop_death/test.cpp index 9205b10aa75..5d3996e6f7c 100644 --- a/tests/std/tests/P0896R4_views_drop_death/test.cpp +++ b/tests/std/tests/P0896R4_views_drop_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -17,11 +15,11 @@ void test_constructor_negative_size() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; -#ifdef _DEBUG +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_constructor_negative_size, }); -#endif // _DEBUG +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0896R4_views_drop_while_death/test.cpp b/tests/std/tests/P0896R4_views_drop_while_death/test.cpp index 9cce078838d..e145c6e017e 100644 --- a/tests/std/tests/P0896R4_views_drop_while_death/test.cpp +++ b/tests/std/tests/P0896R4_views_drop_while_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -48,10 +46,12 @@ void test_view_begin() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_view_predicate, test_view_begin, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0896R4_views_filter_death/test.cpp b/tests/std/tests/P0896R4_views_filter_death/test.cpp index 6a79aa699af..d6f119b6ea2 100644 --- a/tests/std/tests/P0896R4_views_filter_death/test.cpp +++ b/tests/std/tests/P0896R4_views_filter_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -180,11 +178,6 @@ int main(int argc, char* argv[]) { test_iter_swap_value_initialized_iterator_left, test_iter_swap_value_initialized_iterator_right, }); -#else // ^^^ test everything / test only _CONTAINER_DEBUG_LEVEL cases vvv - exec.add_death_tests({ - test_view_predicate, - test_view_begin, - }); #endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); diff --git a/tests/std/tests/P0896R4_views_iota_death/test.cpp b/tests/std/tests/P0896R4_views_iota_death/test.cpp index d38a5ad9a73..43ea1041ed4 100644 --- a/tests/std/tests/P0896R4_views_iota_death/test.cpp +++ b/tests/std/tests/P0896R4_views_iota_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -54,7 +52,7 @@ void test_misordered_iterator_sentinel_vector_iter() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; -#ifdef _DEBUG +#if _ITERATOR_DEBUG_LEVEL != 0 struct S {}; exec.add_death_tests({ @@ -124,7 +122,7 @@ int main(int argc, char* argv[]) { test_misordered_iterator_sentinel_vector_iter, test_misordered_iterator_sentinel_vector_iter, }); -#endif // _DEBUG +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0896R4_views_take_death/test.cpp b/tests/std/tests/P0896R4_views_take_death/test.cpp index 54c26053f52..325100b5477 100644 --- a/tests/std/tests/P0896R4_views_take_death/test.cpp +++ b/tests/std/tests/P0896R4_views_take_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -17,11 +15,11 @@ void test_constructor_negative_size() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; -#ifdef _DEBUG +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_constructor_negative_size, }); -#endif // _DEBUG +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P0896R4_views_take_while_death/test.cpp b/tests/std/tests/P0896R4_views_take_while_death/test.cpp index 3ebc5d93dd9..34e3da9769a 100644 --- a/tests/std/tests/P0896R4_views_take_while_death/test.cpp +++ b/tests/std/tests/P0896R4_views_take_while_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -51,11 +49,13 @@ void test_view_const_end() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_view_predicate, test_view_end, test_view_const_end, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P1502R1_standard_library_header_units/env.lst b/tests/std/tests/P1502R1_standard_library_header_units/env.lst index 90f83ac9b67..3fc0a727c79 100644 --- a/tests/std/tests/P1502R1_standard_library_header_units/env.lst +++ b/tests/std/tests/P1502R1_standard_library_header_units/env.lst @@ -3,7 +3,7 @@ RUNALL_INCLUDE ..\..\..\universal_prefix.lst RUNALL_CROSSLIST -* PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER /Zc:preprocessor" +* PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /Zc:preprocessor" RUNALL_CROSSLIST * PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=20 /std:c++20" * PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=23 /std:c++latest" diff --git a/tests/std/tests/P1899R3_views_stride_death/test.cpp b/tests/std/tests/P1899R3_views_stride_death/test.cpp index ffe1afd65e6..0cebca9f4b1 100644 --- a/tests/std/tests/P1899R3_views_stride_death/test.cpp +++ b/tests/std/tests/P1899R3_views_stride_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -66,10 +64,6 @@ int main(int argc, char* argv[]) { test_iterator_advance_past_end_with_integer_overflow, test_iterator_advance_negative_min, }); -#else // ^^^ test everything / test only _CONTAINER_DEBUG_LEVEL case vvv - exec.add_death_tests({ - test_view_negative_stride, - }); #endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); diff --git a/tests/std/tests/P2374R4_views_cartesian_product_death/test.cpp b/tests/std/tests/P2374R4_views_cartesian_product_death/test.cpp index 65b850caafb..9becd5d078b 100644 --- a/tests/std/tests/P2374R4_views_cartesian_product_death/test.cpp +++ b/tests/std/tests/P2374R4_views_cartesian_product_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -79,11 +77,6 @@ int main(int argc, char* argv[]) { test_iterator_differencing, test_iterator_and_default_sentinel_differencing, }); -#else // ^^^ test everything / test only _CONTAINER_DEBUG_LEVEL cases vvv - exec.add_death_tests({ - test_view_size, - test_view_const_size, - }); #endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); diff --git a/tests/std/tests/P2442R1_views_chunk_death/test.cpp b/tests/std/tests/P2442R1_views_chunk_death/test.cpp index a62cfdfac64..026e1661311 100644 --- a/tests/std/tests/P2442R1_views_chunk_death/test.cpp +++ b/tests/std/tests/P2442R1_views_chunk_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -110,11 +108,6 @@ int main(int argc, char* argv[]) { test_fwd_iterator_advance_past_end_with_integer_overflow, test_fwd_iterator_advance_negative_min, }); -#else // ^^^ test everything / test only _CONTAINER_DEBUG_LEVEL cases vvv - exec.add_death_tests({ - test_view_negative_size_forward_range, - test_view_negative_size_input_range, - }); #endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); diff --git a/tests/std/tests/P2442R1_views_slide_death/test.cpp b/tests/std/tests/P2442R1_views_slide_death/test.cpp index 794f1e69076..fc2b1dc11bd 100644 --- a/tests/std/tests/P2442R1_views_slide_death/test.cpp +++ b/tests/std/tests/P2442R1_views_slide_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -23,10 +21,12 @@ void test_view_zero_window_size() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_view_negative_window_size, test_view_zero_window_size, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/P2443R1_views_chunk_by_death/test.cpp b/tests/std/tests/P2443R1_views_chunk_by_death/test.cpp index 07965975201..f414c1ac072 100644 --- a/tests/std/tests/P2443R1_views_chunk_by_death/test.cpp +++ b/tests/std/tests/P2443R1_views_chunk_by_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -106,11 +104,6 @@ int main(int argc, char* argv[]) { test_operator_postdecrement_value_initialized_iterator, test_operator_postdecrement_before_begin, }); -#else // ^^^ test everything / test only _CONTAINER_DEBUG_LEVEL cases vvv - exec.add_death_tests({ - test_view_predicate, - test_view_begin, - }); #endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); diff --git a/tests/std/tests/P2474R2_views_repeat_death/test.cpp b/tests/std/tests/P2474R2_views_repeat_death/test.cpp index 77ea4d02909..920a926135c 100644 --- a/tests/std/tests/P2474R2_views_repeat_death/test.cpp +++ b/tests/std/tests/P2474R2_views_repeat_death/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -129,6 +127,7 @@ void test_iter_sub_neg_huge() { int main(int argc, char* argv[]) { std_testing::death_test_executive exec; +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_view_lvalue_negative, test_view_rvalue_negative, @@ -155,5 +154,7 @@ int main(int argc, char* argv[]) { test_iter_sub_neg_huge, test_iter_sub_neg_huge, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 + return exec.run(argc, argv); } diff --git a/tests/std/tests/P2502R2_generator_death/test.cpp b/tests/std/tests/P2502R2_generator_death/test.cpp index edf602a32c4..990f5639e7f 100644 --- a/tests/std/tests/P2502R2_generator_death/test.cpp +++ b/tests/std/tests/P2502R2_generator_death/test.cpp @@ -5,8 +5,6 @@ int main() {} #else // ^^^ workaround / no workaround vvv -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -43,12 +41,14 @@ void test_end_iterator_incrementation() { int main(int argc, char** argv) { std_testing::death_test_executive exec; +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_begin_after_initial_suspend_point, test_begin_after_moving_from, test_end_iterator_dereference, test_end_iterator_incrementation, }); +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/VSO_0000000_list_iterator_debugging/test.cpp b/tests/std/tests/VSO_0000000_list_iterator_debugging/test.cpp index fae346f53c5..cd9730af067 100644 --- a/tests/std/tests/VSO_0000000_list_iterator_debugging/test.cpp +++ b/tests/std/tests/VSO_0000000_list_iterator_debugging/test.cpp @@ -532,7 +532,7 @@ int main(int argc, char* argv[]) { }); #endif // _ITERATOR_DEBUG_LEVEL == 2 -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_case_empty_front_bad, test_case_empty_cfront_bad, @@ -541,7 +541,7 @@ int main(int argc, char* argv[]) { test_case_pop_front_bad, test_case_pop_back_bad, }); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/VSO_0000000_string_view_idl/test.cpp b/tests/std/tests/VSO_0000000_string_view_idl/test.cpp index 7b52fcb5c17..d96ce9cf42e 100644 --- a/tests/std/tests/VSO_0000000_string_view_idl/test.cpp +++ b/tests/std/tests/VSO_0000000_string_view_idl/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include @@ -237,21 +235,21 @@ int main(int argc, char* argv[]) { test_case_operator_equal_incompatible_value_initialized, test_case_operator_less_incompatible_different_views, test_case_operator_less_incompatible_value_initialized, + test_case_operator_subscript_out_of_range, + test_case_front_empty, + test_case_back_empty, + test_case_remove_prefix_too_large, + test_case_remove_suffix_too_large, test_case_remove_prefix_incompatible, test_case_remove_suffix_incompatible, + test_case_null_constructor, }); #endif // _ITERATOR_DEBUG_LEVEL != 0 + // basic_string_view::_Copy_s() is a non-Standard extension that's unconditionally checked. + // See: https://learn.microsoft.com/en-us/cpp/standard-library/basic-string-view-class?view=msvc-170#_copy_s exec.add_death_tests({ - // These tests are turned on for _ITERATOR_DEBUG_LEVEL == 0 as part of - // VSO-830211 "Macro to enable runtime bounds checking for subscript operator for STL containers" - test_case_operator_subscript_out_of_range, - test_case_front_empty, - test_case_back_empty, - test_case_remove_prefix_too_large, - test_case_remove_suffix_too_large, test_case_Copy_s, - test_case_null_constructor, }); return exec.run(argc, argv); diff --git a/tests/std/tests/VSO_0677157_flist_merge_edge_cases/test.cpp b/tests/std/tests/VSO_0677157_flist_merge_edge_cases/test.cpp index 70a508eb942..dbc4cfbfac1 100644 --- a/tests/std/tests/VSO_0677157_flist_merge_edge_cases/test.cpp +++ b/tests/std/tests/VSO_0677157_flist_merge_edge_cases/test.cpp @@ -267,18 +267,16 @@ int main(int argc, char* argv[]) { test_case_empty_source_bad>, test_case_empty_target_bad, test_case_empty_target_bad>, - test_case_front_bad, - test_case_cfront_bad, }); #endif // _ITERATOR_DEBUG_LEVEL == 2 -#if _CONTAINER_DEBUG_LEVEL > 0 +#if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_case_front_bad, test_case_cfront_bad, test_case_pop_front_bad, }); -#endif // _CONTAINER_DEBUG_LEVEL > 0 +#endif // _ITERATOR_DEBUG_LEVEL != 0 return exec.run(argc, argv); } diff --git a/tests/std/tests/VSO_0830211_container_debugging_range_checks/test.cpp b/tests/std/tests/VSO_0830211_container_debugging_range_checks/test.cpp index 29b47050c76..9b9643b198b 100644 --- a/tests/std/tests/VSO_0830211_container_debugging_range_checks/test.cpp +++ b/tests/std/tests/VSO_0830211_container_debugging_range_checks/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CONTAINER_DEBUG_LEVEL 1 - #include #include #include @@ -203,6 +201,10 @@ struct TestCases { test_case_operator_equal_incompatible_value_initialized, test_case_operator_less_incompatible_different_views, test_case_operator_less_incompatible_value_initialized, + test_case_operator_subscript_out_of_range_empty, + test_case_operator_subscript_out_of_range, + test_case_front_empty, + test_case_back_empty, }); if constexpr (Traits::has_arrow) { @@ -211,14 +213,9 @@ struct TestCases { test_case_operator_arrow_end_iterator, }); } -#endif // _ITERATOR_DEBUG_LEVEL != 0 - - exec.add_death_tests({ - test_case_operator_subscript_out_of_range_empty, - test_case_operator_subscript_out_of_range, - test_case_front_empty, - test_case_back_empty, - }); +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv + (void) exec; +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ } }; diff --git a/tests/std/tests/modules_20_matrix.lst b/tests/std/tests/modules_20_matrix.lst index 22a3a5ea9d4..6ccb872fd81 100644 --- a/tests/std/tests/modules_20_matrix.lst +++ b/tests/std/tests/modules_20_matrix.lst @@ -3,7 +3,7 @@ RUNALL_INCLUDE ..\..\universal_prefix.lst RUNALL_CROSSLIST -* PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER /Zc:preprocessor" +* PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /Zc:preprocessor" RUNALL_CROSSLIST * PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=20 /std:c++20" * PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=23 /std:c++latest" diff --git a/tests/std/tests/prefix.lst b/tests/std/tests/prefix.lst index ca509bbe8fc..167a64e537d 100644 --- a/tests/std/tests/prefix.lst +++ b/tests/std/tests/prefix.lst @@ -3,4 +3,4 @@ RUNALL_INCLUDE ..\..\universal_prefix.lst RUNALL_CROSSLIST -* PM_CL="/FIforce_include.hpp /w14365 /w14668 /w15267 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER" +* PM_CL="/FIforce_include.hpp /w14365 /w14668 /w15267 /D_ENFORCE_FACET_SPECIALIZATIONS=1" diff --git a/tests/tr1/prefix.lst b/tests/tr1/prefix.lst index 5d1ecb45c88..09eacd9984d 100644 --- a/tests/tr1/prefix.lst +++ b/tests/tr1/prefix.lst @@ -3,4 +3,4 @@ RUNALL_INCLUDE ..\universal_prefix.lst RUNALL_CROSSLIST -* PM_CL="/FIforce_include.hpp /w14668 /w15267 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_CRT_SECURE_NO_WARNINGS /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER" +* PM_CL="/FIforce_include.hpp /w14668 /w15267 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_CRT_SECURE_NO_WARNINGS"