From: Jonathan Wakely Date: Mon, 9 Dec 2024 17:35:24 +0000 (+0000) Subject: libstdc++: Skip redundant assertions in std::span construction [PR117966] X-Git-Tag: releases/gcc-12.5.0~218 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b0f505650310c11455ee7d34f95008658d3e655;p=thirdparty%2Fgcc.git libstdc++: Skip redundant assertions in std::span construction [PR117966] As PR c++/117966 shows, the Debug Mode checks cause a compilation error for a global constexpr std::span. Those debug checks are redundant when constructing from an array or a range, because we already know we have a valid range and we know its size. Instead of delegating to the std::span(contiguous_iterator, contiguous_iterator) constructor, just initialize the data members directly. libstdc++-v3/ChangeLog: PR libstdc++/117966 * include/std/span (span(T (&)[N])): Do not delegate to constructor that performs redundant checks. (span(array&), span(const array&)): Likewise. (span(Range&&), span(const span&)): Likewise. * testsuite/23_containers/span/117966.cc: New test. (cherry picked from commit e95bda027e0b81922c1bf44770674190bdf787e8) --- diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index 251fed91abf..2b68ac42ba8 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -183,21 +183,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION requires (_Extent == dynamic_extent || _ArrayExtent == _Extent) constexpr span(type_identity_t (&__arr)[_ArrayExtent]) noexcept - : span(static_cast(__arr), _ArrayExtent) + : _M_ptr(__arr), _M_extent(_ArrayExtent) { } template requires __is_compatible_array<_Tp, _ArrayExtent>::value constexpr span(array<_Tp, _ArrayExtent>& __arr) noexcept - : span(static_cast(__arr.data()), _ArrayExtent) + : _M_ptr(__arr.data()), _M_extent(_ArrayExtent) { } template requires __is_compatible_array::value constexpr span(const array<_Tp, _ArrayExtent>& __arr) noexcept - : span(static_cast(__arr.data()), _ArrayExtent) + : _M_ptr(__arr.data()), _M_extent(_ArrayExtent) { } template @@ -211,7 +211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION span(_Range&& __range) noexcept(noexcept(ranges::data(__range)) && noexcept(ranges::size(__range))) - : span(ranges::data(__range), ranges::size(__range)) + : _M_ptr(ranges::data(__range)), _M_extent(ranges::size(__range)) { if constexpr (extent != dynamic_extent) { @@ -229,7 +229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr explicit(extent != dynamic_extent && _OExtent == dynamic_extent) span(const span<_OType, _OExtent>& __s) noexcept - : _M_extent(__s.size()), _M_ptr(__s.data()) + : _M_ptr(__s.data()), _M_extent(__s.size()) { if constexpr (extent != dynamic_extent) { diff --git a/libstdc++-v3/testsuite/23_containers/span/117966.cc b/libstdc++-v3/testsuite/23_containers/span/117966.cc new file mode 100644 index 00000000000..8bbb5ca1e07 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/span/117966.cc @@ -0,0 +1,13 @@ +// { dg-options "-D_GLIBCXX_DEBUG" } +// { dg-do compile { target c++20 } } + +// Bug 117966 +// constexpr std::span construction fails to compile with D_GLIBCXX_DEBUG + +#include +#include + +struct A { + constexpr A(std::span) {} +}; +constexpr A val{std::array{0x11, 0x22}};