On Mon, 7 Jul 2025 at 10:13, Tomasz Kaminski <tkami...@redhat.com> wrote: > > > > On Mon, Jul 7, 2025 at 11:09 AM Jonathan Wakely <jwak...@redhat.com> wrote: >> >> On Fri, 4 Jul 2025 at 09:30, Luc Grosheintz <luc.groshei...@gmail.com> wrote: >> > >> > Previously the prerequisite of the extents ctors that >> > >> > static_extent(i) == dynamic_extent || extent(i) == other.extent(i). >> > >> > was not checked. This commit adds the __glibcxx_assert and test them. >> > >> > libstdc++-v3/ChangeLog: >> > >> > * include/std/mdspan (extents): Check prerequisite of the ctor that >> > static_extent(i) == dynamic_extent || extent(i) == other.extent(i). >> > * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: >> > Test the implemented prerequisite. >> > >> > Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> >> > --- >> > libstdc++-v3/include/std/mdspan | 13 +++++++ >> > .../mdspan/extents/class_mandates_neg.cc | 2 ++ >> > .../mdspan/extents/extents_mismatch_neg.cc | 35 +++++++++++++++++++ >> > 3 files changed, 50 insertions(+) >> > create mode 100644 >> > libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc >> > >> > diff --git a/libstdc++-v3/include/std/mdspan >> > b/libstdc++-v3/include/std/mdspan >> > index cf20553aaa5..1d6cdc93d80 100644 >> > --- a/libstdc++-v3/include/std/mdspan >> > +++ b/libstdc++-v3/include/std/mdspan >> > @@ -110,10 +110,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> > return __se; >> > } >> > >> > + template<size_t _OtherRank, typename _GetOtherExtent> >> > + constexpr bool >> > + _S_is_compatible_extents(_GetOtherExtent __get_extent) noexcept >> >> Was this intended to be a static member function? > > Yes, it should be. I will also adjust that locally.
Thanks, OK for trunk with that change. >> >> >> > + { >> > + if constexpr (_OtherRank == _S_rank) >> > + for (size_t __i = 0; __i < _S_rank; ++__i) >> > + if (_Extents[__i] != dynamic_extent >> > + && !cmp_equal(_Extents[__i], >> > _S_int_cast(__get_extent(__i)))) >> > + return false; >> > + return true; >> > + } >> > + >> > template<size_t _OtherRank, typename _GetOtherExtent> >> > constexpr void >> > _M_init_dynamic_extents(_GetOtherExtent __get_extent) noexcept >> > { >> > + >> > __glibcxx_assert(_S_is_compatible_extents<_OtherRank>(__get_extent)); >> > for (size_t __i = 0; __i < _S_rank_dynamic; ++__i) >> > { >> > size_t __di = __i; >> > 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 f9c1c019666..67d18feda96 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 >> > @@ -7,6 +7,8 @@ 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" } >> > +// { dg-prune-output "non-constant condition for static assertion" } >> > diff --git >> > a/libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc >> > >> > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc >> > new file mode 100644 >> > index 00000000000..b35e5310d41 >> > --- /dev/null >> > +++ >> > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc >> > @@ -0,0 +1,35 @@ >> > +// { dg-do compile { target c++23 } } >> > +#include<mdspan> >> > + >> > +#include <cstdint> >> > + >> > +constexpr size_t dyn = std::dynamic_extent; >> > + >> > +constexpr bool >> > +test_dyn2sta_extents_mismatch_00() >> > +{ >> > + auto e0 = std::extents<int, dyn>{1}; >> > + [[maybe_unused]] auto e1 = std::extents<int, 2>{e0}; // { >> > dg-error "expansion of" } >> > + return true; >> > +} >> > +static_assert(test_dyn2sta_extents_mismatch_00()); // { >> > dg-error "expansion of" } >> > + >> > +constexpr bool >> > +test_dyn2sta_extents_mismatch_01() >> > +{ >> > + [[maybe_unused]] auto e = std::extents<int, 1, dyn>{2, 2}; // { >> > dg-error "expansion of" } >> > + return true; >> > +} >> > +static_assert(test_dyn2sta_extents_mismatch_01()); // { >> > dg-error "expansion of" } >> > + >> > +constexpr bool >> > +test_dyn2sta_extents_mismatch_02() >> > +{ >> > + std::array<int, 2> exts{2, 2}; >> > + [[maybe_unused]] auto e = std::extents<int, 1, dyn>{exts}; // { >> > dg-error "expansion of" } >> > + return true; >> > +} >> > +static_assert(test_dyn2sta_extents_mismatch_02()); // { >> > dg-error "expansion of" } >> > + >> > +// { dg-prune-output "non-constant condition for static assertion" } >> > +// { dg-prune-output "__glibcxx_assert" } >> > -- >> > 2.49.0 >> > >>