Converting the __strides values using __index_type_cast asserts
that they are non-negative and each value is representable as
index_type.

libstdc++-v3/ChangeLog:

        * include/std/mdspan
        (layout_stride::mapping::mapping(const extent_type&, span<...>):
        Convert strides using __index_type_cast, which bring asserts
        for negative and unrepresentable values.
        * testsuite/23_containers/mdspan/layouts/stride_neg.cc: New test.
---
Tested on x86_64-linux locally. OK for trunk?

 libstdc++-v3/include/std/mdspan               |  3 +-
 .../mdspan/layouts/stride_neg.cc              | 31 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc

diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index f5556f35fa1..5e1c4d8b1a4 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -1891,7 +1891,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        : _M_extents(__exts)
        {
          for (size_t __i = 0; __i < extents_type::rank(); ++__i)
-           _M_strides[__i] = index_type(as_const(__strides[__i]));
+           _M_strides[__i]
+              = __mdspan::__index_type_cast<index_type>(__strides[__i]);
        }
 
       template<typename _OIndexType>
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc
new file mode 100644
index 00000000000..153560bc82f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++23 } }
+#include <mdspan>
+
+#include "../layout_traits.h"
+#include <cstdint>
+
+constexpr size_t dyn = std::dynamic_extent;
+
+constexpr bool
+test_stride_overflow()
+{
+  auto exts = std::extents<uint8_t, dyn, dyn>(1, 3);
+  auto n = size_t(1) << 9;
+  auto m = std::layout_stride::mapping(exts, std::array{n, 1zu}); // { 
dg-error "expansion of" }
+  (void) m;
+  return true;
+}
+static_assert(test_stride_overflow()); // { dg-error "expansion of" }
+
+constexpr bool
+test_stride_negative()
+{
+  auto exts = std::extents<std::size_t, dyn, dyn>(1, 3);
+  auto m = std::layout_stride::mapping(exts, std::array{1, -4}); // { dg-error 
"expansion of" } 
+  (void) m;
+  return true;
+}
+static_assert(test_stride_negative()); // { dg-error "expansion of" } 
+
+// { dg-prune-output "non-constant condition for static assertion" }
+// { dg-prune-output "__glibcxx_assert_fail()" }
-- 
2.54.0

Reply via email to