[libcxx-commits] [libcxx] 4122db1 - [libc++][hardening] Categorize most assertions inside the container classes.
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 20 10:14:55 PDT 2023
Author: varconst
Date: 2023-07-20T10:14:43-07:00
New Revision: 4122db1fbdeb7a9c5a7c8f0cd7afedd53754eaad
URL: https://github.com/llvm/llvm-project/commit/4122db1fbdeb7a9c5a7c8f0cd7afedd53754eaad
DIFF: https://github.com/llvm/llvm-project/commit/4122db1fbdeb7a9c5a7c8f0cd7afedd53754eaad.diff
LOG: [libc++][hardening] Categorize most assertions inside the container classes.
This introduces:
- `_LIBCPP_ASSERT_VALID_INPUT_RANGE`;
- `_LIBCPP_ASSERT_VALID_CONTAINER_ACCESS`;
- `_LIBCPP_ASSERT_VALID_ITERATOR_ACCESS`;
- `_LIBCPP_ASSERT_VALID_ALLOCATOR`;
- `_LIBCPP_ASSERT_INTERNAL`.
Differential Revision: https://reviews.llvm.org/D155349
Added:
Modified:
libcxx/include/__config
libcxx/include/__expected/expected.h
libcxx/include/__functional/function.h
libcxx/include/__iterator/bounded_iter.h
libcxx/include/__mdspan/extents.h
libcxx/include/__tree
libcxx/include/array
libcxx/include/deque
libcxx/include/list
libcxx/include/map
libcxx/include/optional
libcxx/include/span
libcxx/include/string
libcxx/include/string_view
libcxx/include/unordered_map
libcxx/include/unordered_set
libcxx/include/vector
Removed:
################################################################################
diff --git a/libcxx/include/__config b/libcxx/include/__config
index c147b0baa4534b..41addf9a04122f 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -233,9 +233,27 @@
//
// #define _LIBCPP_ENABLE_DEBUG_MODE 1
-// Available checks:
-
-// TODO(hardening): add documentation for
diff erent checks here.
+// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
+// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
+//
+// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
+// a sentinel, 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_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
+// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
+// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
+// `optional` and `function` are considered one-element containers for the purposes of this check.
+//
+// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between 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.
# ifndef _LIBCPP_ENABLE_HARDENED_MODE
# define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT
@@ -256,26 +274,43 @@
# endif
// Hardened mode checks.
+
+// clang-format off
# 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)
-// TODO(hardening): more checks to be added here...
+// Enabled checks.
+# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_ELEMENT_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_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
// 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)
-// TODO(hardening): more checks to be added here...
+// All checks enabled.
+# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
+# define _LIBCPP_ASSERT_COMPATIBLE_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)
+
+// Disable all checks if hardening is not enabled.
-// Disable all checks if neither the hardened mode nor the debug mode is 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_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
+# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
# endif // _LIBCPP_ENABLE_HARDENED_MODE
+// clang-format on
// } HARDENING
diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index edcffc8b4579f9..7d57aa4db5f952 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -526,32 +526,32 @@ class expected {
// [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_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
return std::move(__union_.__val_);
}
@@ -594,22 +594,22 @@ class expected {
}
_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_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
return std::move(__union_.__unex_);
}
@@ -1217,7 +1217,7 @@ class expected<_Tp, _Err> {
_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_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
}
_LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
@@ -1233,22 +1233,22 @@ class expected<_Tp, _Err> {
}
_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_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_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
index 124be82fe4ebfa..3c6e3f450d8b1c 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -923,7 +923,7 @@ class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
{ }
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 @@ class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
}
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
index 6212ebb0bf900b..2a667648871c4c 100644
--- a/libcxx/include/__iterator/bounded_iter.h
+++ b/libcxx/include/__iterator/bounded_iter.h
@@ -81,8 +81,7 @@ struct __bounded_iter {
_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(
- __begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
+ _LIBCPP_ASSERT_INTERNAL(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
}
template <class _It>
@@ -93,19 +92,19 @@ struct __bounded_iter {
//
// 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_ELEMENT_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_ELEMENT_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[](
diff erence_type __n) const _NOEXCEPT {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ _LIBCPP_ASSERT_VALID_ELEMENT_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
index 8c9f12147b5726..42355678d60ccc 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -197,17 +197,17 @@ struct __maybe_static_array {
// 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_ELEMENT_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_ELEMENT_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_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
return __value(__i);
}
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index e7761d2ad21657..92b5e65e115827 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -376,9 +376,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
{
_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
index 2983b67edb7f6a..3fc25d4c30623d 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -229,12 +229,12 @@ struct _LIBCPP_TEMPLATE_VIS array
// 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<T, N>");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
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<T, N>");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
return __elems_[__n];
}
@@ -342,13 +342,13 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
// element access:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reference operator[](size_type) _NOEXCEPT {
- _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::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<T, 0>::operator[] on a zero-sized array");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
__libcpp_unreachable();
}
@@ -366,25 +366,25 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reference front() _NOEXCEPT {
- _LIBCPP_ASSERT_UNCATEGORIZED(false, "cannot call array<T, 0>::front() on a zero-sized array");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::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<T, 0>::front() on a zero-sized array");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::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<T, 0>::back() on a zero-sized array");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::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<T, 0>::back() on a zero-sized array");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
__libcpp_unreachable();
}
};
diff --git a/libcxx/include/deque b/libcxx/include/deque
index b063680500cce4..777f9354259873 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -2597,7 +2597,7 @@ template <class _Tp, class _Allocator>
void
deque<_Tp, _Allocator>::pop_back()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "deque::pop_back called on an empty deque");
+ _LIBCPP_ASSERT_VALID_ELEMENT_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
index 2512259461500b..37bed3cd89fc96 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -695,10 +695,10 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
__is_nothrow_swappable<allocator_type>::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_COMPATIBLE_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());
@@ -879,25 +879,25 @@ public:
_LIBCPP_INLINE_VISIBILITY
reference front()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::front called on empty list");
+ _LIBCPP_ASSERT_VALID_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
return base::__end_.__prev_->__as_node()->__value_;
}
@@ -1587,7 +1587,7 @@ template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::pop_front()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::pop_front() called with empty list");
+ _LIBCPP_ASSERT_VALID_ELEMENT_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);
@@ -1601,7 +1601,7 @@ template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::pop_back()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "list::pop_back() called on an empty list");
+ _LIBCPP_ASSERT_VALID_ELEMENT_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);
@@ -1615,7 +1615,7 @@ template <class _Tp, class _Alloc>
typename list<_Tp, _Alloc>::iterator
list<_Tp, _Alloc>::erase(const_iterator __p)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__p != end(),
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
"list::erase(iterator) called with a non-dereferenceable iterator");
__node_allocator& __na = base::__node_alloc();
__link_pointer __n = __p.__ptr_;
@@ -1752,8 +1752,8 @@ template <class _Tp, class _Alloc>
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_INPUT_RANGE(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
index d21f6b9bc11054..4152d58a2f8844 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -1463,7 +1463,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
insert_return_type insert(node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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));
@@ -1471,7 +1471,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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>(
__hint.__i_, _VSTD::move(__nh));
@@ -1490,32 +1490,32 @@ public:
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
#endif
@@ -2195,7 +2195,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to multimap::insert()");
return __tree_.template __node_handle_insert_multi<node_type>(
_VSTD::move(__nh));
@@ -2203,7 +2203,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to multimap::insert()");
return __tree_.template __node_handle_insert_multi<node_type>(
__hint.__i_, _VSTD::move(__nh));
@@ -2223,32 +2223,32 @@ public:
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_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
index 6ead4b1e881af0..3a81734208b301 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -412,7 +412,7 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
_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 @@ struct __optional_storage_base<_Tp, true>
_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 @@ public:
add_pointer_t<value_type const>
operator->() const
{
- _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator-> called on a disengaged value");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
return _VSTD::addressof(this->__get());
}
@@ -1005,7 +1005,7 @@ public:
add_pointer_t<value_type>
operator->()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator-> called on a disengaged value");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
return _VSTD::addressof(this->__get());
}
@@ -1014,7 +1014,7 @@ public:
const value_type&
operator*() const& noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return this->__get();
}
@@ -1023,7 +1023,7 @@ public:
value_type&
operator*() & noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return this->__get();
}
@@ -1032,7 +1032,7 @@ public:
value_type&&
operator*() && noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return _VSTD::move(this->__get());
}
@@ -1041,7 +1041,7 @@ public:
const value_type&&
operator*() const&& noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(this->has_value(), "optional operator* called on a disengaged value");
+ _LIBCPP_ASSERT_VALID_ELEMENT_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
index 582bdbf5c14069..b050dfe6e340e5 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -233,7 +233,7 @@ public:
constexpr explicit span(_It __first, size_type __count)
: __data_{_VSTD::to_address(__first)} {
(void)__count;
- _LIBCPP_ASSERT_UNCATEGORIZED(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
}
template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
@@ -242,8 +242,8 @@ public:
// [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_UNCATEGORIZED(
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent");
}
@@ -261,7 +261,8 @@ public:
template <__span_compatible_range<element_type> _Range>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} {
- _LIBCPP_ASSERT_UNCATEGORIZED(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
}
template <__span_array_convertible<element_type> _OtherElementType>
@@ -273,7 +274,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept
: __data_{__other.data()} {
- _LIBCPP_ASSERT_UNCATEGORIZED(_Extent == __other.size(), "size mismatch in span's constructor (other span)");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ _Extent == __other.size(), "size mismatch in span's constructor (other span)");
}
template <size_t _Count>
@@ -295,14 +297,14 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span<T, N>::first(count): count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span<T, N>::last(count): count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range");
return {data() + size() - __count, __count};
}
@@ -323,11 +325,12 @@ public:
constexpr span<element_type, dynamic_extent>
subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
- _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size() - __offset,
- "span<T, N>::subspan(offset, count): offset + count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
return {data() + __offset, __count};
}
@@ -337,19 +340,19 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__idx < size(), "span<T, N>::operator[](index): index out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range");
return __data_[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span<T, N>::front() on empty span");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
return __data_[0];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span<T, N>::back() on empty span");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");
return __data_[size()-1];
}
@@ -419,7 +422,8 @@ public:
template <__span_compatible_iterator<element_type> _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 <size_t _Sz>
@@ -448,7 +452,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(_Count <= size(), "span<T>::first<Count>(): Count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range");
return span<element_type, _Count>{data(), _Count};
}
@@ -456,21 +460,21 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(_Count <= size(), "span<T>::last<Count>(): Count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range");
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span<T>::first(count): count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size(), "span<T>::last(count): count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range");
return {data() + size() - __count, __count};
}
@@ -478,9 +482,10 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> subspan() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
- _LIBCPP_ASSERT_UNCATEGORIZED(_Count == dynamic_extent || _Count <= size() - _Offset,
- "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ _Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset,
+ "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
@@ -488,11 +493,11 @@ public:
_LIBCPP_INLINE_VISIBILITY
subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
- _LIBCPP_ASSERT_UNCATEGORIZED(__count <= size() - __offset,
- "span<T>::subspan(offset, count): offset + count out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
return {data() + __offset, __count};
}
@@ -502,19 +507,19 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__idx < size(), "span<T>::operator[](index): index out of range");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range");
return __data_[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span<T>::front() on empty span");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");
return __data_[0];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "span<T>::back() on empty span");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span");
return __data_[size()-1];
}
diff --git a/libcxx/include/string b/libcxx/include/string
index eeff013c0e8c45..4b96273698166d 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1206,12 +1206,12 @@ public:
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_ELEMENT_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_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
@@ -1307,22 +1307,22 @@ public:
_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_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
return *(data() + size() - 1);
}
@@ -1812,16 +1812,16 @@ private:
_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_;
}
@@ -2585,7 +2585,7 @@ template <class _Iterator, class _Sentinel>
_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();
@@ -3161,7 +3161,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
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_ELEMENT_ACCESS(
+ __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
iterator __b = begin();
size_type __r = static_cast<size_type>(__pos - __b);
erase(__r, 1);
@@ -3173,7 +3174,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
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<size_type>(__first - __b);
erase(__r, static_cast<size_type>(__last - __first));
@@ -3185,7 +3186,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
void
basic_string<_CharT, _Traits, _Allocator>::pop_back()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "string::pop_back(): string is already empty");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty");
__erase_to_end(size() - 1);
}
@@ -3368,7 +3369,7 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
__is_nothrow_swappable<allocator_type>::value)
#endif
{
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ _LIBCPP_ASSERT_COMPATIBLE_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
index 2d00a4e0123660..3149fe250578fb 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -323,8 +323,8 @@ public:
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 @@ public:
// [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_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
}
_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
@@ -419,13 +419,14 @@ public:
_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_ELEMENT_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_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"),
+ __data_[__size_ - 1];
}
_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
@@ -435,7 +436,7 @@ public:
_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_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()");
__data_ += __n;
__size_ -= __n;
}
@@ -443,7 +444,7 @@ public:
_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_ELEMENT_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
index 4772667dbbf624..8d83063bbeaeb3 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -1457,7 +1457,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
insert_return_type insert(node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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));
@@ -1465,7 +1465,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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>(
__hint.__i_, _VSTD::move(__nh));
@@ -1486,32 +1486,32 @@ public:
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_unique(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_unique(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_unique(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_unique(__source.__table_);
}
#endif
@@ -2294,7 +2294,7 @@ private:
_LIBCPP_INLINE_VISIBILITY
iterator insert(node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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<node_type>(
_VSTD::move(__nh));
@@ -2302,7 +2302,7 @@ private:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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<node_type>(
__hint.__i_, _VSTD::move(__nh));
@@ -2323,32 +2323,32 @@ private:
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_multi(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_multi(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_multi(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_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
index 2e2f4caddb9938..5e47f12446ff93 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -812,7 +812,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
insert_return_type insert(node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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));
@@ -820,7 +820,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __h, node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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>(
__h, _VSTD::move(__nh));
@@ -840,32 +840,32 @@ public:
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__table_.__node_handle_merge_unique(__source.__table_);
}
template<class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__table_.__node_handle_merge_unique(__source.__table_);
}
template<class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__table_.__node_handle_merge_unique(__source.__table_);
}
template<class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
__table_.__node_handle_merge_unique(__source.__table_);
}
#endif
@@ -1487,7 +1487,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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<node_type>(
_VSTD::move(__nh));
@@ -1495,7 +1495,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ _LIBCPP_ASSERT_COMPATIBLE_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<node_type>(
__hint, _VSTD::move(__nh));
@@ -1516,32 +1516,32 @@ public:
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_multi(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_multi(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
return __table_.__node_handle_merge_multi(__source.__table_);
}
template <class _H2, class _P2>
_LIBCPP_INLINE_VISIBILITY
void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
- "merging container with incompatible allocator");
+ _LIBCPP_ASSERT_COMPATIBLE_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
index 0adf9f6a2011ca..19bf49513a667b 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -619,22 +619,22 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "front() called on an empty vector");
+ _LIBCPP_ASSERT_VALID_ELEMENT_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_ELEMENT_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_ELEMENT_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_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
return *(this->__end_ - 1);
}
@@ -1531,7 +1531,7 @@ inline _LIBCPP_HIDE_FROM_ABI
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_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
@@ -1541,7 +1541,7 @@ inline _LIBCPP_HIDE_FROM_ABI
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_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
@@ -1687,7 +1687,7 @@ inline
void
vector<_Tp, _Allocator>::pop_back()
{
- _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), "vector::pop_back called on an empty vector");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector::pop_back called on an empty vector");
this->__destruct_at_end(this->__end_ - 1);
}
@@ -1697,7 +1697,7 @@ inline _LIBCPP_HIDE_FROM_ABI
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __position)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__position != end(),
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__position != end(),
"vector::erase(iterator) called with a non-dereferenceable iterator");
diff erence_type __ps = __position - cbegin();
pointer __p = this->__begin_ + __ps;
@@ -1710,7 +1710,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
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 @@ vector<_Tp, _Allocator>::swap(vector& __x)
__is_nothrow_swappable<allocator_type>::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_COMPATIBLE_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 <class _Allocator>
template <class _ForwardIterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
void vector<bool, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last,
diff erence_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 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
typename vector<bool, _Allocator>::iterator
vector<bool, _Allocator>::__insert_with_size(const_iterator __position, _ForwardIterator __first, _Sentinel __last,
diff erence_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<size_type>(__n_signed);
iterator __r;
size_type __c = capacity();
More information about the libcxx-commits
mailing list