aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/libcxx/include/__mdspan/extents.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/libcxx/include/__mdspan/extents.h')
-rw-r--r--contrib/llvm-project/libcxx/include/__mdspan/extents.h63
1 files changed, 42 insertions, 21 deletions
diff --git a/contrib/llvm-project/libcxx/include/__mdspan/extents.h b/contrib/llvm-project/libcxx/include/__mdspan/extents.h
index 42355678d60c..a510220d4096 100644
--- a/contrib/llvm-project/libcxx/include/__mdspan/extents.h
+++ b/contrib/llvm-project/libcxx/include/__mdspan/extents.h
@@ -171,11 +171,14 @@ public:
_TStatic __static_val = _StaticValues::__get(__i);
if (__static_val == _DynTag) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i];
- }
- // Precondition check
- else
- _LIBCPP_ASSERT_UNCATEGORIZED(__values[__i] == static_cast<_TDynamic>(__static_val),
- "extents construction: mismatch of provided arguments with static extents.");
+ } else
+ // Not catching this could lead to out of bounds errors later
+ // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[5], 5);
+ // Right-hand-side construction looks ok with allocation and size matching,
+ // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not 5
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __values[__i] == static_cast<_TDynamic>(__static_val),
+ "extents construction: mismatch of provided arguments with static extents.");
}
}
@@ -187,11 +190,14 @@ public:
_TStatic __static_val = _StaticValues::__get(__i);
if (__static_val == _DynTag) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]);
- }
- // Precondition check
- else
- _LIBCPP_ASSERT_UNCATEGORIZED(static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
- "extents construction: mismatch of provided arguments with static extents.");
+ } else
+ // Not catching this could lead to out of bounds errors later
+ // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[N], span<int,1>(&N));
+ // Right-hand-side construction looks ok with allocation and size matching,
+ // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not N
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
+ "extents construction: mismatch of provided arguments with static extents.");
}
}
@@ -310,28 +316,37 @@ public:
(sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
_LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
: __vals_(static_cast<index_type>(__dynvals)...) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
template <class _OtherIndexType, size_t _Size>
- requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v<index_type, _OtherIndexType> &&
+ requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+ is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
(_Size == __rank_ || _Size == __rank_dynamic_))
explicit(_Size != __rank_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept
: __vals_(span(__exts)) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan m(ptr, dextents<char, 1>(array<unsigned,1>(200))); leads to an extent of -56 on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
template <class _OtherIndexType, size_t _Size>
- requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v<index_type, _OtherIndexType> &&
+ requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+ is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
(_Size == __rank_ || _Size == __rank_dynamic_))
explicit(_Size != __rank_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept
: __vals_(__exts) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__are_representable_as<index_type>(__exts),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. array a{200u}; mdspan<int, dextents<char,1>> m(ptr, extents(span<unsigned,1>(a))); leads to an extent of -56
+ // on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__exts),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
private:
@@ -380,10 +395,16 @@ public:
for (size_t __r = 0; __r < rank(); __r++) {
if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. dextents<char,1>> e(dextents<unsigned,1>(200)) leads to an extent of -56 on e
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan<int, extents<int, 10>> m = mdspan<int, dextents<int, 1>>(new int[5], 5);
+ // Right-hand-side construction was ok, but m now thinks its range is 10 not 5
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
(_Values::__static_value(__r) == dynamic_extent) ||
(static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))),
"extents construction: mismatch of provided arguments with static extents.");