On Tue, 7 Jul 2026 at 11:21, Tomasz Kamiński <[email protected]> wrote:
>
> 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?

OK for trunk. I think this makes sense for gcc-16 too?

>
>  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