https://gcc.gnu.org/g:0babc6f29f7c29215674b3ee58d5dd17ce7b3849
commit r16-659-g0babc6f29f7c29215674b3ee58d5dd17ce7b3849 Author: Luc Grosheintz <luc.groshei...@gmail.com> Date: Wed May 14 21:13:52 2025 +0200 libstdc++: Fix class mandate for extents. The standard states that the IndexType must be a signed or unsigned integer. This mandate was implemented using `std::is_integral_v`. Which also includes (among others) char and bool, which neither signed nor unsigned integers. libstdc++-v3/ChangeLog: * include/std/mdspan: Implement the mandate for extents as signed or unsigned integer and not any interal type. Remove leading underscores from names in static_assert message. * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: Check that extents<char,...> and extents<bool,...> are invalid. Adjust dg-prune-output pattern. * testsuite/23_containers/mdspan/extents/misc.cc: Update tests to avoid `char` and `bool` as IndexType. Reviewed-by: Tomasz KamiĆski <tkami...@redhat.com> Reviewed-by: Jonathan Wakely <jwak...@redhat.com> Diff: --- libstdc++-v3/include/std/mdspan | 5 +++-- .../23_containers/mdspan/extents/class_mandates_neg.cc | 12 ++++++++---- libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc | 8 ++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index aee96dda7cd0..47cfa405e442 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -163,10 +163,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _IndexType, size_t... _Extents> class extents { - static_assert(is_integral_v<_IndexType>, "_IndexType must be integral."); + static_assert(__is_standard_integer<_IndexType>::value, + "IndexType must be a signed or unsigned integer type"); static_assert( (__mdspan::__valid_static_extent<_Extents, _IndexType> && ...), - "Extents must either be dynamic or representable as _IndexType"); + "Extents must either be dynamic or representable as IndexType"); public: using index_type = _IndexType; diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc index b654e3920a8a..f9c1c0196669 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc @@ -1,8 +1,12 @@ // { dg-do compile { target c++23 } } #include<mdspan> -std::extents<char, size_t(1) << 9> e1; // { dg-error "from here" } -std::extents<double, 1> e2; // { dg-error "from here" } -// { dg-prune-output "dynamic or representable as _IndexType" } -// { dg-prune-output "must be integral" } +#include <cstdint> + +std::extents<uint8_t, size_t(1) << 9> e1; // { dg-error "from here" } +std::extents<char, 1> e2; // { dg-error "from here" } +std::extents<bool, 1> e3; // { dg-error "from here" } +std::extents<double, 1> e4; // { dg-error "from here" } +// { dg-prune-output "dynamic or representable as IndexType" } +// { dg-prune-output "signed or unsigned integer" } // { dg-prune-output "invalid use of incomplete type" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc index 16204aaaa75a..e71fdc542305 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc @@ -1,6 +1,7 @@ // { dg-do run { target c++23 } } #include <mdspan> +#include <cstdint> #include <testsuite_hooks.h> constexpr size_t dyn = std::dynamic_extent; @@ -20,7 +21,6 @@ static_assert(std::is_same_v<std::extents<int, 1, 2>::rank_type, size_t>); static_assert(std::is_unsigned_v<std::extents<int, 2>::size_type>); static_assert(std::is_unsigned_v<std::extents<unsigned int, 2>::size_type>); -static_assert(std::is_same_v<std::extents<char, 2>::index_type, char>); static_assert(std::is_same_v<std::extents<int, 2>::index_type, int>); static_assert(std::is_same_v<std::extents<unsigned int, 2>::index_type, unsigned int>); @@ -49,7 +49,7 @@ static_assert(check_rank_return_types<int, 1>()); // Check that the static extents don't take up space. static_assert(sizeof(std::extents<int, 1, dyn>) == sizeof(int)); -static_assert(sizeof(std::extents<char, 1, dyn>) == sizeof(char)); +static_assert(sizeof(std::extents<short, 1, dyn>) == sizeof(short)); template<typename Extents> class Container @@ -58,7 +58,7 @@ class Container [[no_unique_address]] std::extents<size_t> b0; }; -static_assert(sizeof(Container<std::extents<char, 1, 2>>) == sizeof(int)); +static_assert(sizeof(Container<std::extents<short, 1, 2>>) == sizeof(int)); static_assert(sizeof(Container<std::extents<size_t, 1, 2>>) == sizeof(int)); // operator= @@ -103,7 +103,7 @@ test_deduction_all() test_deduction<0>(); test_deduction<1>(1); test_deduction<2>(1.0, 2.0f); - test_deduction<3>(int(1), char(2), size_t(3)); + test_deduction<3>(int(1), short(2), size_t(3)); return true; }