]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Apply LWG4351 to CTAD of span/mdspan.
authorLuc Grosheintz <luc.grosheintz@gmail.com>
Sat, 6 Sep 2025 13:11:57 +0000 (15:11 +0200)
committerTomasz Kamiński <tkaminsk@redhat.com>
Wed, 10 Sep 2025 10:46:57 +0000 (12:46 +0200)
The concept __integral_constant_like doesn't consider traits with a
boolean member `value` as an integer constant. This is done to reject
various completely unrelated traits like is_const, is_abstract, etc.

LWG4351 adjusts the check to strip references and cv qualifiers before
checking if `value` is bool. The immediate context is constant_wrapper
which defines:

    template<...>
    struct constant_wrapper
    {
      static constexpr const auto& value = ...;
    };

Without LWG4351, std::cw<true> and std::cw<false> would both be
considered integer constants (by __integral_constant_like); but both
std::{true,false}_type are not considered integer constants. Hence,
LWG4351 removes inconsistent behaviour between std::integral_constant
and std::constant_wrapper.

libstdc++-v3/ChangeLog:

* include/std/span (__integral_constant_like): Use
remove_cvref_t before checking if _Tp::value is boolean.
* testsuite/23_containers/mdspan/extents/misc.cc: Update test.
* testsuite/23_containers/mdspan/mdspan.cc: Ditto.
* testsuite/23_containers/span/deduction.cc: Ditto.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
libstdc++-v3/include/std/span
libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
libstdc++-v3/testsuite/23_containers/span/deduction.cc

index f9aa3c77e8e1195e2c3f40c8dd7fc68f51273127..580891135657cf57e402429caa02386fd1c16119 100644 (file)
@@ -479,10 +479,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // deduction guides
   namespace __detail
   {
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 4351. integral-constant-like needs more remove_cvref_t
     template<typename _Tp>
       concept __integral_constant_like =
        is_integral_v<remove_cvref_t<decltype(_Tp::value)>>
-       && !is_same_v<bool, remove_const_t<decltype(_Tp::value)>>
+       && !is_same_v<bool, remove_cvref_t<decltype(_Tp::value)>>
        && convertible_to<_Tp, decltype(_Tp::value)>
        && equality_comparable_with<_Tp, decltype(_Tp::value)>
        && bool_constant<_Tp() == _Tp::value>::value
index 94086653a745295753a4e64124ba02b778a2cf07..33d6f947f0bcc4e800a6be53573e36e11d979949 100644 (file)
@@ -121,7 +121,7 @@ test_deduction_from_constant()
   verify(std::extents(1, c2), std::extents<size_t, dyn, 2>{1});
   verify(std::extents(c2), std::extents<size_t, 2>{});
   verify(std::extents(1, c2), std::extents<size_t, dyn, 2>{1});
-  verify(std::extents(std::cw<true>, c2), std::extents<size_t, 1, 2>{});
+  verify(std::extents(std::cw<true>, c2), std::extents<size_t, dyn, 2>{1});
 #endif
   return true;
 }
index ca100b4f314a3e918efb2c4506d9d47169c683b2..a92a0554417083d315fb8fd6e0a7787fb01cc877 100644 (file)
@@ -304,8 +304,7 @@ test_from_pointer_and_constant()
   auto c3 = std::constant_wrapper<3>{};
   verify(std::mdspan(ptr, 2, c3), std::extents(2, i3));
   verify(std::mdspan(ptr, 2, std::cw<3>), std::extents(2, i3));
-  verify(std::mdspan(ptr, std::cw<true>, std::cw<3>),
-        std::extents(std::cw<1>, i3));
+  verify(std::mdspan(ptr, std::cw<true>, std::cw<3>), std::extents(1, i3));
 #endif
   return true;
 }
index e958ad5d6db0bb86fcd7fdc0bc7bcd8daa42da40..55a586254e86e16aae78cf55a8c54e1fbfa936bd 100644 (file)
@@ -99,6 +99,6 @@ test01()
   static_assert( is_static_span<long, 4>(s17) );
 
   std::span s18(a.data(), std::cw<true>);
-  static_assert( is_static_span<long, 1>(s18) );
+  static_assert( is_dynamic_span<long>(s18) );
 #endif
 }