On Mon, Jul 7, 2025 at 3:29 PM Luc Grosheintz <luc.groshei...@gmail.com> wrote:
> > On 7/4/25 10:29, Luc Grosheintz wrote: > > Previously, the prerequisite that the arguments passed to operator() are > > a multi-dimensional index (of extents()) was not checked. > > > > Both mapping::operator() and mdspan::operator[] have the same > > prerequisite. Since, mdspan must check the prerequisite for user-defined > > layout mappings, the preference is to check in mdspan. > > > > Because out-of-bounds accesses are very common it's nevertheless useful > > to check the prerequisite in mapping::operator(). This is relevant for > > cases where the layout mappings are used without mdspan. This commit > > check the prerequisites via _GLIBCXX_DEBUG_ASSERTs and adds the required > > Could you please locally fix this typo in the commit message? > > s/check/checks/ > Done. > > > > tests. > > > > More discussion in the email chain starting at: > > > > https://gcc.gnu.org/pipermail/libstdc++/2025-July/062265.html > > > > libstdc++-v3/ChangeLog: > > > > * include/std/mdspan: Check prerequisites of > > layout_*::operator() with _GLIBCXX_DEBUG_ASSERTs. > > * > testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc: > > Add tests for prerequisites. > > > > Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> > > --- > > libstdc++-v3/include/std/mdspan | 5 ++++ > > .../mdspan/layouts/debug/out_of_bounds_neg.cc | 30 +++++++++++++++++++ > > 2 files changed, 35 insertions(+) > > create mode 100644 > libstdc++-v3/testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc > > > > diff --git a/libstdc++-v3/include/std/mdspan > b/libstdc++-v3/include/std/mdspan > > index c72a64094b7..cf20553aaa5 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_DEBUG_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_DEBUG_ASSERT(cmp_less(__ind_arr[__pos], > > + __exts.extent(__pos))); > > __res += __ind_arr[__pos] * __mult; > > __mult *= __exts.extent(__pos); > > }; > > @@ -822,6 +825,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > { > > auto __update = [&, __pos = 0u](_IndexType __idx) mutable > > { > > + _GLIBCXX_DEBUG_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/debug/out_of_bounds_neg.cc > b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc > > new file mode 100644 > > index 00000000000..fb8ff01e8aa > > --- /dev/null > > +++ > b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc > > @@ -0,0 +1,30 @@ > > +// { dg-do compile { target c++23 } } > > +// { dg-require-debug-mode "" } > > +#include<mdspan> > > + > > +template<typename Layout> > > + constexpr bool > > + test_out_of_bounds_1d() > > + { > > + auto m = typename Layout::mapping<std::extents<int, 0>>{}; > > + (void) m(0); // { dg-error "expansion of" } > > + return true; > > + } > > +static_assert(test_out_of_bounds_1d<std::layout_left>()); // { dg-error > "expansion of" } > > +static_assert(test_out_of_bounds_1d<std::layout_right>()); // { > dg-error "expansion of" } > > +static_assert(test_out_of_bounds_1d<std::layout_stride>()); // { > dg-error "expansion of" } > > + > > +template<typename Layout> > > + constexpr bool > > + test_out_of_bounds_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_out_of_bounds_3d<std::layout_left>()); // { dg-error > "expansion of" } > > +static_assert(test_out_of_bounds_3d<std::layout_right>()); // { > dg-error "expansion of" } > > +static_assert(test_out_of_bounds_3d<std::layout_stride>()); // { > dg-error "expansion of" } > > + > > +// { dg-prune-output "non-constant condition for static assertion" } > > +// { dg-prune-output "__glibcxx_assert" } > >