https://gcc.gnu.org/g:74ddf1792ae3538ee829f2c399dfcb75bfae8fd3
commit r16-2094-g74ddf1792ae3538ee829f2c399dfcb75bfae8fd3 Author: Luc Grosheintz <luc.groshei...@gmail.com> Date: Fri Jul 4 10:29:44 2025 +0200 libstdc++: Check prerequisite of extents::extents. 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. Reviewed-by: Tomasz KamiĆski <tkami...@redhat.com> Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> Diff: --- 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(+) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index 1fdcae634419..d97fa22e4f03 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> + static constexpr bool + _S_is_compatible_extents(_GetOtherExtent __get_extent) noexcept + { + 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 f9c1c0196669..67d18feda96c 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 000000000000..b35e5310d415 --- /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" }