[gcc(refs/users/mikael/heads/pr121185_v01)] libstdc++: Fix forwarding of custom IndexType in mdspan [PR121061]

Mikael Morin mikael@gcc.gnu.org
Thu Jul 24 08:04:21 GMT 2025


https://gcc.gnu.org/g:23e4a4637eefcb566785b7ca4373871b6973d60b

commit 23e4a4637eefcb566785b7ca4373871b6973d60b
Author: Luc Grosheintz <luc.grosheintz@gmail.com>
Date:   Wed Jul 16 15:45:45 2025 +0200

    libstdc++: Fix forwarding of custom IndexType in mdspan [PR121061]
    
    The second bug report in PR121061 is that the conversion of custom
    OtherIndexType to IndexType is incorrectly not done via r-value
    references.
    
    This commit fixes the forwarding issue, adds a custom IndexType called
    RValueInt, which only allows conversion to int via r-value reference.
    
            PR libstdc++/121061
    
    libstdc++-v3/ChangeLog:
    
            * include/std/mdspan (extents::extents): Perform conversion to
            index_type of an r-value reference.
            (layout_left::mapping::operator()): Ditto.
            (layout_right::mapping::operator()): Ditto.
            (layout_stride::mapping::operator()): Ditto.
            * testsuite/23_containers/mdspan/extents/custom_integer.cc: Add
            tests for RValueInt and MutatingInt.
            * testsuite/23_containers/mdspan/int_like.h (RValueInt): Add.
            * testsuite/23_containers/mdspan/layouts/mapping.cc: Test with
            RValueInt.
            * testsuite/23_containers/mdspan/mdspan.cc: Ditto.
    
    Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
    Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
    Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>

Diff:
---
 libstdc++-v3/include/std/mdspan                                   | 8 ++++----
 .../testsuite/23_containers/mdspan/extents/custom_integer.cc      | 3 +++
 libstdc++-v3/testsuite/23_containers/mdspan/int_like.h            | 7 +++++++
 libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc    | 1 +
 libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc             | 2 ++
 5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 930997e95360..271fdb5d8c7d 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -285,7 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		  || sizeof...(_OIndexTypes) == rank_dynamic())
 	constexpr explicit extents(_OIndexTypes... __exts) noexcept
 	: _M_exts(span<const _IndexType, sizeof...(_OIndexTypes)>(
-	    initializer_list{_S_storage::_S_int_cast(__exts)...}))
+	    initializer_list{static_cast<_IndexType>(std::move(__exts))...}))
 	{ }
 
       template<typename _OIndexType, size_t _Nm>
@@ -602,7 +602,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	operator()(_Indices... __indices) const noexcept
 	{
 	  return __mdspan::__linear_index_left(_M_extents,
-	    static_cast<index_type>(__indices)...);
+	    static_cast<index_type>(std::move(__indices))...);
 	}
 
       static constexpr bool
@@ -741,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	operator()(_Indices... __indices) const noexcept
 	{
 	  return __mdspan::__linear_index_right(
-	    _M_extents, static_cast<index_type>(__indices)...);
+	    _M_extents, static_cast<index_type>(std::move(__indices))...);
 	}
 
       static constexpr bool
@@ -963,7 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	operator()(_Indices... __indices) const noexcept
 	{
 	  return __mdspan::__linear_index_strides(*this,
-	    static_cast<index_type>(__indices)...);
+	    static_cast<index_type>(std::move(__indices))...);
 	}
 
       static constexpr bool
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
index 92c2ebb46e1b..99de4015ef31 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
@@ -85,9 +85,12 @@ main()
   test_shape_all<IntLike, true>();
   test_shape_all<ThrowingInt, false>();
   test_shape_all<MutatingInt, false>();
+  test_shape_all<RValueInt, false>();
 
   test_pack_all<int, true>();
   test_pack_all<IntLike, true>();
   test_pack_all<ThrowingInt, false>();
+  test_pack_all<MutatingInt, true>();
+  test_pack_all<RValueInt, true>();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
index f4f4a7731931..310dd8ddf207 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
@@ -6,6 +6,7 @@ enum class CustomIndexKind
   Const,
   Throwing,
   Mutating,
+  RValue,
 };
 
 template<CustomIndexKind Kind>
@@ -42,6 +43,11 @@ template<CustomIndexKind Kind>
     requires (Kind == CustomIndexKind::Mutating)
     { return _M_i; }
 
+    constexpr
+    operator int() && noexcept
+    requires (Kind == CustomIndexKind::RValue)
+    { return _M_i; }
+
   private:
     int _M_i;
   };
@@ -49,6 +55,7 @@ template<CustomIndexKind Kind>
 using IntLike = CustomIndexType<CustomIndexKind::Const>;
 using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>;
 using MutatingInt = CustomIndexType<CustomIndexKind::Mutating>;
+using RValueInt = CustomIndexType<CustomIndexKind::RValue>;
 
 struct NotIntLike
 { };
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
index 6742fa11a514..58bce5144354 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
@@ -527,6 +527,7 @@ template<typename Layout>
       {
 	test_linear_index_all<Layout, IntLike>();
 	test_linear_index_all<Layout, MutatingInt>();
+	test_linear_index_all<Layout, RValueInt>();
       }
 
     test_required_span_size_all<Layout>();
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
index 22ec68ea2d1d..be4a1b1c17e4 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
@@ -694,6 +694,7 @@ main()
   test_from_int_like<IntLike, true, true>();
   test_from_int_like<ThrowingInt, false, false>();
   test_from_int_like<MutatingInt, true, false>();
+  test_from_int_like<RValueInt, true, false>();
 
   test_from_opaque_accessor();
   test_from_base_class_accessor();
@@ -705,6 +706,7 @@ main()
   test_access<IntLike, true, true>();
   test_access<ThrowingInt, false, false>();
   test_access<MutatingInt, true, false>();
+  test_access<RValueInt, true, false>();
 
   test_swap();
   static_assert(test_swap());


More information about the Libstdc++-cvs mailing list