Previously the prerequisite that the arguments passed to operator() are a multi-dimensional index (of extents()) was not checked.
This commit adds the __glibcxx_asserts and the required tests. libstdc++-v3/ChangeLog: * include/std/mdspan: Check prerequisites of layout_*::operator(). * testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc: Add tests for prerequisites. Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> --- libstdc++-v3/include/std/mdspan | 4 +++ .../mdspan/layouts/class_mandate_neg.cc | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index c72a64094b7..39d02ac08df 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -441,6 +441,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _IndexType __mult = 1; auto __update = [&, __pos = 0u](_IndexType __idx) mutable { + __glibcxx_assert(cmp_less(__idx, __exts.extent(__pos))); __res += __idx * __mult; __mult *= __exts.extent(__pos); ++__pos; @@ -651,6 +652,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __update = [&, __pos = __exts.rank()](_IndexType) mutable { --__pos; + __glibcxx_assert(cmp_less(__ind_arr[__pos], + __exts.extent(__pos))); __res += __ind_arr[__pos] * __mult; __mult *= __exts.extent(__pos); }; @@ -822,6 +825,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { auto __update = [&, __pos = 0u](_IndexType __idx) mutable { + __glibcxx_assert(cmp_less(__idx, __m.extents().extent(__pos))); __res += __idx * __m.stride(__pos++); }; (__update(__indices), ...); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc index 7091153daba..f5aab22aff0 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc @@ -45,4 +45,30 @@ auto b5 = B<5, std::layout_stride, std::layout_right>(); // { dg-error "require auto b6 = B<6, std::layout_stride, std::layout_left>(); // { dg-error "required from" } auto b7 = B<7, std::layout_stride, std::layout_stride>(); // { dg-error "required from" } +template<typename Layout> + constexpr bool + test_linear_index_0d() + { + auto m = typename Layout::mapping<std::extents<int, 0>>{}; + (void) m(0); // { dg-error "expansion of" } + return true; + } +static_assert(test_linear_index_0d<std::layout_left>()); // { dg-error "expansion of" } +static_assert(test_linear_index_0d<std::layout_right>()); // { dg-error "expansion of" } +static_assert(test_linear_index_0d<std::layout_stride>()); // { dg-error "expansion of" } + +template<typename Layout> + constexpr bool + test_linear_index_3d() + { + auto m = typename Layout::mapping<std::extents<int, 3, 5, 7>>{}; + (void) m(2, 5, 5); // { dg-error "expansion of" } + return true; + } +static_assert(test_linear_index_3d<std::layout_left>()); // { dg-error "expansion of" } +static_assert(test_linear_index_3d<std::layout_right>()); // { dg-error "expansion of" } +static_assert(test_linear_index_3d<std::layout_stride>()); // { dg-error "expansion of" } + // { dg-prune-output "must be representable as index_type" } +// { dg-prune-output "non-constant condition for static assertion" } +// { dg-prune-output "__glibcxx_assert" } -- 2.49.0