mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-10-03 23:48:37 +00:00
libstdc++: Check prerequisites of layout_*::operator().
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 checks the prerequisites via _GLIBCXX_DEBUG_ASSERTs and adds the required 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. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
This commit is contained in:
committed by
Tomasz Kamiński
parent
90f7df6194
commit
4d86e4cda0
@@ -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), ...);
|
||||
|
||||
@@ -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" }
|
||||
Reference in New Issue
Block a user