diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -233,9 +233,31 @@ // // #define _LIBCPP_ENABLE_DEBUG_MODE 1 -// Available checks: +// Available assertion categories: -// TODO(hardening): add documentation for different checks here. +// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and +// a count, or a `std::range`) given as input to library functions are valid: +// - the sentinel is reachable from the begin iterator; +// - TODO(hardening): where applicable, the input range and the output range do not overlap; +// - TODO(hardening): both iterators refer to the same container. +// +// - `_LIBCPP_ASSERT_VALID_CONTAINER_ACCESS` -- checks any calls into a container to make sure they don't attempt to +// access a non-existent element. Types like `optional` and `function` are considered one-element containers for the +// purposes of this check. This check only applies to member functions of containers, not any access made purely via +// iterators. +// +// - `_LIBCPP_ASSERT_VALID_ITERATOR_ACCESS` -- checks that iterators being dereferenced are valid. Bounded iterators +// must be enabled in the ABI for this check to work (otherwise it will be a no-op). +// +// - `_LIBCPP_ASSERT_VALID_ALLOCATOR` -- checks any operations that merge or swap containers to make sure the containers +// have compatible allocators. +// +// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on +// user input. +// +// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet. + +// TODO(hardening): add documentation for any new checks here. # ifndef _LIBCPP_ENABLE_HARDENED_MODE # define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT @@ -256,24 +278,45 @@ # endif // Hardened mode checks. + # if _LIBCPP_ENABLE_HARDENED_MODE -// TODO(hardening): Once we categorize assertions, only enable the ones that we really want here. -# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) +// Enabled checks. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ITERATOR_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +// TODO(hardening): Don't enable uncategorized assertions in the hardened mode. +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) +// Disabled checks. +# define _LIBCPP_ASSERT_VALID_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) // TODO(hardening): more checks to be added here... // Debug mode checks. + # elif _LIBCPP_ENABLE_DEBUG_MODE -// TODO(hardening): Once we categorize assertions, only enable the ones that we really want here. -# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) +// All checks enabled. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ITERATOR_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) // TODO(hardening): more checks to be added here... -// Disable all checks if neither the hardened mode nor the debug mode is enabled. +// Disable all checks if hardening is not enabled. + # else -# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) -// TODO: more checks to be added here... +// All checks disabled. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_ITERATOR_ACCESS(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) +// TODO(hardening): more checks to be added here... # endif // _LIBCPP_ENABLE_HARDENED_MODE diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -526,32 +526,32 @@ // [expected.object.obs], observers _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator-> requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value"); return std::addressof(__union_.__val_); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator-> requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value"); return std::addressof(__union_.__val_); } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator* requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); return __union_.__val_; } _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator* requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); return __union_.__val_; } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator* requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); return std::move(__union_.__val_); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator* requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); return std::move(__union_.__val_); } @@ -594,22 +594,22 @@ } _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return __union_.__unex_; } _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return __union_.__unex_; } _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return std::move(__union_.__unex_); } _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return std::move(__union_.__unex_); } @@ -1217,7 +1217,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__has_val_, "expected::operator* requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); } _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { @@ -1233,22 +1233,22 @@ } _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return __union_.__unex_; } _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return __union_.__unex_; } _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return std::move(__union_.__unex_); } _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!__has_val_, "expected::error requires the expected to contain an error"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); return std::move(__union_.__unex_); } diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -923,7 +923,7 @@ { } virtual __base<_Rp(_ArgTypes...)>* __clone() const { - _LIBCPP_ASSERT_UNCATEGORIZED(false, + _LIBCPP_ASSERT_INTERNAL(false, "Block pointers are just pointers, so they should always fit into " "std::function's small buffer optimization. This function should " "never be invoked."); @@ -943,7 +943,7 @@ } virtual void destroy_deallocate() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, + _LIBCPP_ASSERT_INTERNAL(false, "Block pointers are just pointers, so they should always fit into " "std::function's small buffer optimization. This function should " "never be invoked."); diff --git a/libcxx/include/__iterator/bounded_iter.h b/libcxx/include/__iterator/bounded_iter.h --- a/libcxx/include/__iterator/bounded_iter.h +++ b/libcxx/include/__iterator/bounded_iter.h @@ -81,7 +81,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter( _Iterator __current, _Iterator __begin, _Iterator __end) : __current_(__current), __begin_(__begin), __end_(__end) { - _LIBCPP_ASSERT_UNCATEGORIZED( + _LIBCPP_ASSERT_INTERNAL( __begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); } @@ -93,19 +93,19 @@ // // These operations check that the iterator is dereferenceable, that is within [begin, end). _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED( + _LIBCPP_ASSERT_VALID_ITERATOR_ACCESS( __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator"); return *__current_; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED( + _LIBCPP_ASSERT_VALID_ITERATOR_ACCESS( __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator"); return std::__to_address(__current_); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED( + _LIBCPP_ASSERT_VALID_ITERATOR_ACCESS( __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range"); return __current_[__n]; } diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h --- a/libcxx/include/__mdspan/extents.h +++ b/libcxx/include/__mdspan/extents.h @@ -197,17 +197,17 @@ // access functions _LIBCPP_HIDE_FROM_ABI static constexpr _TStatic __static_value(size_t __i) noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__i < __size_, "extents access: index must be less than rank"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__i < __size_, "extents access: index must be less than rank"); return _StaticValues::__get(__i); } _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic __value(size_t __i) const { - _LIBCPP_ASSERT_UNCATEGORIZED(__i < __size_, "extents access: index must be less than rank"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__i < __size_, "extents access: index must be less than rank"); _TStatic __static_val = _StaticValues::__get(__i); return __static_val == _DynTag ? __dyn_vals_[_DynamicIdxMap::__get(__i)] : static_cast<_TDynamic>(__static_val); } _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic operator[](size_t __i) const { - _LIBCPP_ASSERT_UNCATEGORIZED(__i < __size_, "extents access: index must be less than rank"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__i < __size_, "extents access: index must be less than rank"); return __value(__i); } diff --git a/libcxx/include/__tree b/libcxx/include/__tree --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -376,9 +376,7 @@ { _LIBCPP_ASSERT_UNCATEGORIZED(__root != nullptr, "Root node should not be null"); _LIBCPP_ASSERT_UNCATEGORIZED(__z != nullptr, "The node to remove should not be null"); -#if _LIBCPP_ENABLE_DEBUG_MODE - _LIBCPP_ASSERT_UNCATEGORIZED(std::__tree_invariant(__root), "The tree invariants should hold"); -#endif + _LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold"); // __z will be removed from the tree. Client still needs to destruct/deallocate it // __y is either __z, or if __z has two children, __tree_next(__z). // __y will have at most one child. diff --git a/libcxx/include/array b/libcxx/include/array --- a/libcxx/include/array +++ b/libcxx/include/array @@ -229,12 +229,12 @@ // element access: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__n < _Size, "out-of-bounds access in std::array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__n < _Size, "out-of-bounds access in std::array"); return __elems_[__n]; } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__n < _Size, "out-of-bounds access in std::array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__n < _Size, "out-of-bounds access in std::array"); return __elems_[__n]; } @@ -342,13 +342,13 @@ // element access: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array::operator[] on a zero-sized array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(false, "cannot call array::operator[] on a zero-sized array"); __libcpp_unreachable(); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array::operator[] on a zero-sized array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(false, "cannot call array::operator[] on a zero-sized array"); __libcpp_unreachable(); } @@ -366,25 +366,25 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array::front() on a zero-sized array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(false, "cannot call array::front() on a zero-sized array"); __libcpp_unreachable(); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array::front() on a zero-sized array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(false, "cannot call array::front() on a zero-sized array"); __libcpp_unreachable(); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array::back() on a zero-sized array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(false, "cannot call array::back() on a zero-sized array"); __libcpp_unreachable(); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array::back() on a zero-sized array"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(false, "cannot call array::back() on a zero-sized array"); __libcpp_unreachable(); } }; diff --git a/libcxx/include/deque b/libcxx/include/deque --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -2600,7 +2600,7 @@ void deque<_Tp, _Allocator>::pop_back() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "deque::pop_back called on an empty deque"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "deque::pop_back called on an empty deque"); size_type __old_sz = size(); size_type __old_start = __start_; allocator_type& __a = __alloc(); diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -677,10 +677,10 @@ __is_nothrow_swappable::value) #endif { - _LIBCPP_ASSERT_UNCATEGORIZED(__alloc_traits::propagate_on_container_swap::value || - this->__node_alloc() == __c.__node_alloc(), - "list::swap: Either propagate_on_container_swap must be true" - " or the allocators must compare equal"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__alloc_traits::propagate_on_container_swap::value || + this->__node_alloc() == __c.__node_alloc(), + "list::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); using _VSTD::swap; _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc()); swap(__sz(), __c.__sz()); @@ -844,25 +844,25 @@ _LIBCPP_INLINE_VISIBILITY reference front() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::front called on empty list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "list::front called on empty list"); return base::__end_.__next_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY const_reference front() const { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::front called on empty list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "list::front called on empty list"); return base::__end_.__next_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY reference back() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::back called on empty list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "list::back called on empty list"); return base::__end_.__prev_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY const_reference back() const { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::back called on empty list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "list::back called on empty list"); return base::__end_.__prev_->__as_node()->__value_; } @@ -1498,7 +1498,7 @@ void list<_Tp, _Alloc>::pop_front() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::pop_front() called with empty list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "list::pop_front() called with empty list"); __node_allocator& __na = base::__node_alloc(); __link_pointer __n = base::__end_.__next_; base::__unlink_nodes(__n, __n); @@ -1512,7 +1512,7 @@ void list<_Tp, _Alloc>::pop_back() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::pop_back() called on an empty list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "list::pop_back() called on an empty list"); __node_allocator& __na = base::__node_alloc(); __link_pointer __n = base::__end_.__prev_; base::__unlink_nodes(__n, __n); @@ -1526,7 +1526,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) { - _LIBCPP_ASSERT_UNCATEGORIZED(__p != end(), + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__p != end(), "list::erase(iterator) called with a non-dereferenceable iterator"); __node_allocator& __na = base::__node_alloc(); __link_pointer __n = __p.__ptr_; @@ -1663,8 +1663,8 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) { - _LIBCPP_ASSERT_UNCATEGORIZED(this != _VSTD::addressof(__c), - "list::splice(iterator, list) called with this == &list"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this != _VSTD::addressof(__c), + "list::splice(iterator, list) called with this == &list"); if (!__c.empty()) { __link_pointer __f = __c.__end_.__next_; diff --git a/libcxx/include/map b/libcxx/include/map --- a/libcxx/include/map +++ b/libcxx/include/map @@ -1398,7 +1398,7 @@ _LIBCPP_INLINE_VISIBILITY insert_return_type insert(node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to map::insert()"); return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(_VSTD::move(__nh)); @@ -1406,7 +1406,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __hint, node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to map::insert()"); return __tree_.template __node_handle_insert_unique( __hint.__i_, _VSTD::move(__nh)); @@ -1425,32 +1425,32 @@ _LIBCPP_INLINE_VISIBILITY void merge(map& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __tree_.__node_handle_merge_unique(__source.__tree_); } template _LIBCPP_INLINE_VISIBILITY void merge(map&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __tree_.__node_handle_merge_unique(__source.__tree_); } template _LIBCPP_INLINE_VISIBILITY void merge(multimap& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __tree_.__node_handle_merge_unique(__source.__tree_); } template _LIBCPP_INLINE_VISIBILITY void merge(multimap&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __tree_.__node_handle_merge_unique(__source.__tree_); } #endif @@ -2086,7 +2086,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to multimap::insert()"); return __tree_.template __node_handle_insert_multi( _VSTD::move(__nh)); @@ -2094,7 +2094,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __hint, node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to multimap::insert()"); return __tree_.template __node_handle_insert_multi( __hint.__i_, _VSTD::move(__nh)); @@ -2114,32 +2114,32 @@ _LIBCPP_INLINE_VISIBILITY void merge(multimap& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __tree_.__node_handle_merge_multi(__source.__tree_); } template _LIBCPP_INLINE_VISIBILITY void merge(multimap&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __tree_.__node_handle_merge_multi(__source.__tree_); } template _LIBCPP_INLINE_VISIBILITY void merge(map& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __tree_.__node_handle_merge_multi(__source.__tree_); } template _LIBCPP_INLINE_VISIBILITY void merge(map&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __tree_.__node_handle_merge_multi(__source.__tree_); } #endif diff --git a/libcxx/include/optional b/libcxx/include/optional --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -412,7 +412,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) { - _LIBCPP_ASSERT_UNCATEGORIZED(!has_value(), "__construct called for engaged __optional_storage"); + _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); #if _LIBCPP_STD_VER >= 20 _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...); #else @@ -507,7 +507,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) { - _LIBCPP_ASSERT_UNCATEGORIZED(!has_value(), "__construct called for engaged __optional_storage"); + _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); static_assert(__can_bind_reference<_UArg>(), "Attempted to construct a reference element in tuple from a " "possible temporary"); @@ -996,7 +996,7 @@ add_pointer_t operator->() const { - _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator-> called on a disengaged value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); return _VSTD::addressof(this->__get()); } @@ -1005,7 +1005,7 @@ add_pointer_t operator->() { - _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator-> called on a disengaged value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); return _VSTD::addressof(this->__get()); } @@ -1014,7 +1014,7 @@ const value_type& operator*() const& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return this->__get(); } @@ -1023,7 +1023,7 @@ value_type& operator*() & noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return this->__get(); } @@ -1032,7 +1032,7 @@ value_type&& operator*() && noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return _VSTD::move(this->__get()); } @@ -1041,7 +1041,7 @@ const value_type&& operator*() const&& noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return _VSTD::move(this->__get()); } diff --git a/libcxx/include/span b/libcxx/include/span --- a/libcxx/include/span +++ b/libcxx/include/span @@ -242,7 +242,7 @@ // [span.cons]/10 // Throws: When and what last - first throws. [[maybe_unused]] auto __dist = __last - __first; - _LIBCPP_ASSERT_UNCATEGORIZED(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); _LIBCPP_ASSERT_UNCATEGORIZED( __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); } @@ -295,14 +295,14 @@ _LIBCPP_INLINE_VISIBILITY constexpr span first(size_type __count) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span::first(count): count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__count <= size(), "span::first(count): count out of range"); return {data(), __count}; } _LIBCPP_INLINE_VISIBILITY constexpr span last(size_type __count) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span::last(count): count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__count <= size(), "span::last(count): count out of range"); return {data() + size() - __count, __count}; } @@ -323,11 +323,12 @@ constexpr span subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__offset <= size(), "span::subspan(offset, count): offset out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS( + __offset <= size(), "span::subspan(offset, count): offset out of range"); if (__count == dynamic_extent) return {data() + __offset, size() - __offset}; - _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size() - __offset, - "span::subspan(offset, count): offset + count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS( + __count <= size() - __offset, "span::subspan(offset, count): offset + count out of range"); return {data() + __offset, __count}; } @@ -337,19 +338,19 @@ _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__idx < size(), "span::operator[](index): index out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__idx < size(), "span::operator[](index): index out of range"); return __data_[__idx]; } _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span::front() on empty span"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "span::front() on empty span"); return __data_[0]; } _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span::back() on empty span"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "span::back() on empty span"); return __data_[size()-1]; } @@ -419,7 +420,8 @@ template <__span_compatible_iterator _It, __span_compatible_sentinel_for<_It> _End> _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last) : __data_(_VSTD::to_address(__first)), __size_(__last - __first) { - _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE( + __last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); } template @@ -448,7 +450,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr span first() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(_Count <= size(), "span::first(): Count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(_Count <= size(), "span::first(): Count out of range"); return span{data(), _Count}; } @@ -456,21 +458,21 @@ _LIBCPP_INLINE_VISIBILITY constexpr span last() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(_Count <= size(), "span::last(): Count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(_Count <= size(), "span::last(): Count out of range"); return span{data() + size() - _Count, _Count}; } _LIBCPP_INLINE_VISIBILITY constexpr span first(size_type __count) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span::first(count): count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__count <= size(), "span::first(count): count out of range"); return {data(), __count}; } _LIBCPP_INLINE_VISIBILITY constexpr span last (size_type __count) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span::last(count): count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__count <= size(), "span::last(count): count out of range"); return {data() + size() - __count, __count}; } @@ -478,9 +480,10 @@ _LIBCPP_INLINE_VISIBILITY constexpr span subspan() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(_Offset <= size(), "span::subspan(): Offset out of range"); - _LIBCPP_ASSERT_UNCATEGORIZED(_Count == dynamic_extent || _Count <= size() - _Offset, - "span::subspan(): Offset + Count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS( + _Offset <= size(), "span::subspan(): Offset out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, + "span::subspan(): Offset + Count out of range"); return span{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } @@ -488,11 +491,11 @@ _LIBCPP_INLINE_VISIBILITY subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__offset <= size(), "span::subspan(offset, count): offset out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__offset <= size(), "span::subspan(offset, count): offset out of range"); if (__count == dynamic_extent) return {data() + __offset, size() - __offset}; - _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size() - __offset, - "span::subspan(offset, count): offset + count out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS( + __count <= size() - __offset, "span::subspan(offset, count): offset + count out of range"); return {data() + __offset, __count}; } @@ -502,19 +505,19 @@ _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(__idx < size(), "span::operator[](index): index out of range"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__idx < size(), "span::operator[](index): index out of range"); return __data_[__idx]; } _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span::front() on empty span"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "span::front() on empty span"); return __data_[0]; } _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span::back() on empty span"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "span::back() on empty span"); return __data_[size()-1]; } diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1206,12 +1206,12 @@ bool empty() const _NOEXCEPT {return size() == 0;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__pos <= size(), "string index out of bounds"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__pos <= size(), "string index out of bounds"); return *(data() + __pos); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__pos <= size(), "string index out of bounds"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__pos <= size(), "string index out of bounds"); return *(__get_pointer() + __pos); } @@ -1307,22 +1307,22 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back(); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string::front(): string is empty"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string::front(): string is empty"); return *__get_pointer(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string::front(): string is empty"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string::front(): string is empty"); return *data(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string::back(): string is empty"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string::back(): string is empty"); return *(__get_pointer() + size() - 1); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string::back(): string is empty"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string::back(): string is empty"); return *(data() + size() - 1); } @@ -1812,16 +1812,16 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_short_size(size_type __s) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__s < __min_cap, - "__s should never be greater than or equal to the short string capacity"); + _LIBCPP_ASSERT_INTERNAL( + __s < __min_cap, "__s should never be greater than or equal to the short string capacity"); __r_.first().__s.__size_ = __s; __r_.first().__s.__is_long_ = false; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_short_size() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!__r_.first().__s.__is_long_, - "String has to be short when trying to get the short size"); + _LIBCPP_ASSERT_INTERNAL( + !__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); return __r_.first().__s.__size_; } @@ -2556,7 +2556,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) { - _LIBCPP_ASSERT_UNCATEGORIZED( + _LIBCPP_ASSERT_INTERNAL( __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial"); size_type __cap = capacity(); @@ -3132,7 +3132,8 @@ typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { - _LIBCPP_ASSERT_UNCATEGORIZED(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS( + __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); iterator __b = begin(); size_type __r = static_cast(__pos - __b); erase(__r, 1); @@ -3144,7 +3145,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { - _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "string::erase(first, last) called with invalid range"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range"); iterator __b = begin(); size_type __r = static_cast(__first - __b); erase(__r, static_cast(__last - __first)); @@ -3156,7 +3157,7 @@ void basic_string<_CharT, _Traits, _Allocator>::pop_back() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string::pop_back(): string is already empty"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string::pop_back(): string is already empty"); __erase_to_end(size() - 1); } @@ -3339,7 +3340,7 @@ __is_nothrow_swappable::value) #endif { - _LIBCPP_ASSERT_UNCATEGORIZED( + _LIBCPP_ASSERT_VALID_ALLOCATOR( __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || __alloc() == __str.__alloc(), "swapping non-equal allocators"); diff --git a/libcxx/include/string_view b/libcxx/include/string_view --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -323,8 +323,8 @@ constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end) : __data_(_VSTD::to_address(__begin)), __size_(__end - __begin) { - _LIBCPP_ASSERT_UNCATEGORIZED((__end - __begin) >= 0, - "std::string_view::string_view(iterator, sentinel) received invalid range"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE((__end - __begin) >= 0, + "std::string_view::string_view(iterator, sentinel) received invalid range"); } #endif // _LIBCPP_STD_VER >= 20 @@ -405,7 +405,7 @@ // [string.view.access], element access _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT { - return _LIBCPP_ASSERT_UNCATEGORIZED(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; + return _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; } _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY @@ -419,13 +419,14 @@ _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT { - return _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string_view::front(): string is empty"), __data_[0]; + return _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0]; } _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT { - return _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string_view::back(): string is empty"), __data_[__size_-1]; + return _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "string_view::back(): string is empty"), + __data_[__size_ - 1]; } _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY @@ -435,7 +436,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY void remove_prefix(size_type __n) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__n <= size(), "remove_prefix() can't remove more than size()"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()"); __data_ += __n; __size_ -= __n; } @@ -443,7 +444,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY void remove_suffix(size_type __n) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__n <= size(), "remove_suffix() can't remove more than size()"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()"); __size_ -= __n; } diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -1346,7 +1346,7 @@ _LIBCPP_INLINE_VISIBILITY insert_return_type insert(node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_map::insert()"); return __table_.template __node_handle_insert_unique< node_type, insert_return_type>(_VSTD::move(__nh)); @@ -1354,7 +1354,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __hint, node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_map::insert()"); return __table_.template __node_handle_insert_unique( __hint.__i_, _VSTD::move(__nh)); @@ -1375,32 +1375,32 @@ _LIBCPP_INLINE_VISIBILITY void merge(unordered_map& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_unique(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_map&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_unique(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_multimap& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_unique(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_multimap&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_unique(__source.__table_); } #endif @@ -2107,7 +2107,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_multimap::insert()"); return __table_.template __node_handle_insert_multi( _VSTD::move(__nh)); @@ -2115,7 +2115,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __hint, node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_multimap::insert()"); return __table_.template __node_handle_insert_multi( __hint.__i_, _VSTD::move(__nh)); @@ -2136,32 +2136,32 @@ _LIBCPP_INLINE_VISIBILITY void merge(unordered_multimap& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_multimap&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_map& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_map&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } #endif diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -702,7 +702,7 @@ _LIBCPP_INLINE_VISIBILITY insert_return_type insert(node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_set::insert()"); return __table_.template __node_handle_insert_unique< node_type, insert_return_type>(_VSTD::move(__nh)); @@ -710,7 +710,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __h, node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_set::insert()"); return __table_.template __node_handle_insert_unique( __h, _VSTD::move(__nh)); @@ -730,32 +730,32 @@ _LIBCPP_INLINE_VISIBILITY void merge(unordered_set& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_set&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } #endif @@ -1302,7 +1302,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_multiset::insert()"); return __table_.template __node_handle_insert_multi( _VSTD::move(__nh)); @@ -1310,7 +1310,7 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __hint, node_type&& __nh) { - _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_VALID_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_multiset::insert()"); return __table_.template __node_handle_insert_multi( __hint, _VSTD::move(__nh)); @@ -1331,32 +1331,32 @@ _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_set& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template _LIBCPP_INLINE_VISIBILITY void merge(unordered_set&& __source) { - _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } #endif diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -619,22 +619,22 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "front() called on an empty vector"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "front() called on an empty vector"); return *this->__begin_; } _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "front() called on an empty vector"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "front() called on an empty vector"); return *this->__begin_; } _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "back() called on an empty vector"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "back() called on an empty vector"); return *(this->__end_ - 1); } _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "back() called on an empty vector"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "back() called on an empty vector"); return *(this->__end_ - 1); } @@ -1531,7 +1531,7 @@ typename vector<_Tp, _Allocator>::reference vector<_Tp, _Allocator>::operator[](size_type __n) _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__n < size(), "vector[] index out of bounds"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__n < size(), "vector[] index out of bounds"); return this->__begin_[__n]; } @@ -1541,7 +1541,7 @@ typename vector<_Tp, _Allocator>::const_reference vector<_Tp, _Allocator>::operator[](size_type __n) const _NOEXCEPT { - _LIBCPP_ASSERT_UNCATEGORIZED(__n < size(), "vector[] index out of bounds"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__n < size(), "vector[] index out of bounds"); return this->__begin_[__n]; } @@ -1687,7 +1687,7 @@ void vector<_Tp, _Allocator>::pop_back() { - _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "vector::pop_back called on an empty vector"); + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(!empty(), "vector::pop_back called on an empty vector"); this->__destruct_at_end(this->__end_ - 1); } @@ -1697,7 +1697,7 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __position) { - _LIBCPP_ASSERT_UNCATEGORIZED(__position != end(), + _LIBCPP_ASSERT_VALID_CONTAINER_ACCESS(__position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); pointer __p = this->__begin_ + __ps; @@ -1710,7 +1710,7 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) { - _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "vector::erase(first, last) called with invalid range"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); if (__first != __last) { this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p)); @@ -2003,10 +2003,10 @@ __is_nothrow_swappable::value) #endif { - _LIBCPP_ASSERT_UNCATEGORIZED(__alloc_traits::propagate_on_container_swap::value || - this->__alloc() == __x.__alloc(), - "vector::swap: Either propagate_on_container_swap must be true" - " or the allocators must compare equal"); + _LIBCPP_ASSERT_VALID_ALLOCATOR(__alloc_traits::propagate_on_container_swap::value || + this->__alloc() == __x.__alloc(), + "vector::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); std::swap(this->__begin_, __x.__begin_); std::swap(this->__end_, __x.__end_); std::swap(this->__end_cap(), __x.__end_cap()); @@ -2956,7 +2956,7 @@ template _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void vector::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns) { - _LIBCPP_ASSERT_UNCATEGORIZED(__ns >= 0, "invalid range specified"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__ns >= 0, "invalid range specified"); clear(); @@ -3155,7 +3155,7 @@ typename vector::iterator vector::__insert_with_size(const_iterator __position, _ForwardIterator __first, _Sentinel __last, difference_type __n_signed) { - _LIBCPP_ASSERT_UNCATEGORIZED(__n_signed >= 0, "invalid range specified"); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__n_signed >= 0, "invalid range specified"); const size_type __n = static_cast(__n_signed); iterator __r; size_type __c = capacity();