[PATCH v3 1/5] libstdc++: Check prerequisites of layout_*::operator().
Tomasz Kaminski
tkaminsk@redhat.com
Mon Jul 7 13:56:14 GMT 2025
On Mon, Jul 7, 2025 at 3:29 PM Luc Grosheintz <luc.grosheintz@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.grosheintz@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" }
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250707/6cb7029b/attachment-0001.htm>
More information about the Libstdc++
mailing list