From: Luc Grosheintz Date: Sat, 6 Sep 2025 13:11:57 +0000 (+0200) Subject: libstdc++: Apply LWG4351 to CTAD of span/mdspan. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54cc2cb7bc668fa895329970c862bc5475e9e793;p=thirdparty%2Fgcc.git libstdc++: Apply LWG4351 to CTAD of span/mdspan. 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 and std::cw 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 Signed-off-by: Luc Grosheintz --- diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index f9aa3c77e8e..58089113565 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -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 concept __integral_constant_like = is_integral_v> - && !is_same_v> + && !is_same_v> && convertible_to<_Tp, decltype(_Tp::value)> && equality_comparable_with<_Tp, decltype(_Tp::value)> && bool_constant<_Tp() == _Tp::value>::value diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc index 94086653a74..33d6f947f0b 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc @@ -121,7 +121,7 @@ test_deduction_from_constant() verify(std::extents(1, c2), std::extents{1}); verify(std::extents(c2), std::extents{}); verify(std::extents(1, c2), std::extents{1}); - verify(std::extents(std::cw, c2), std::extents{}); + verify(std::extents(std::cw, c2), std::extents{1}); #endif return true; } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc index ca100b4f314..a92a0554417 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc @@ -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, std::cw<3>), - std::extents(std::cw<1>, i3)); + verify(std::mdspan(ptr, std::cw, std::cw<3>), std::extents(1, i3)); #endif return true; } diff --git a/libstdc++-v3/testsuite/23_containers/span/deduction.cc b/libstdc++-v3/testsuite/23_containers/span/deduction.cc index e958ad5d6db..55a586254e8 100644 --- a/libstdc++-v3/testsuite/23_containers/span/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/span/deduction.cc @@ -99,6 +99,6 @@ test01() static_assert( is_static_span(s17) ); std::span s18(a.data(), std::cw); - static_assert( is_static_span(s18) ); + static_assert( is_dynamic_span(s18) ); #endif }