[PATCH v1] libstdc++: Apply LWG4351 to CTAD of span/mdspan.
Luc Grosheintz
luc.grosheintz@gmail.com
Sat Sep 6 13:11:57 GMT 2025
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.
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
---
libstdc++-v3/include/std/span | 4 +++-
libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc | 2 +-
libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc | 3 +--
libstdc++-v3/testsuite/23_containers/span/deduction.cc | 2 +-
4 files changed, 6 insertions(+), 5 deletions(-)
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<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
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<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;
}
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<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;
}
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<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
}
--
2.51.0
More information about the Libstdc++
mailing list