]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Skip redundant assertions in std::span construction [PR117966]
authorJonathan Wakely <jwakely@redhat.com>
Mon, 9 Dec 2024 17:35:24 +0000 (17:35 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 16 Apr 2025 17:47:39 +0000 (18:47 +0100)
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<T, N>&), span(const array<T, N>&)): Likewise.
(span(Range&&), span(const span<T, N>&)): Likewise.
* testsuite/23_containers/span/117966.cc: New test.

(cherry picked from commit e95bda027e0b81922c1bf44770674190bdf787e8)

libstdc++-v3/include/std/span
libstdc++-v3/testsuite/23_containers/span/117966.cc [new file with mode: 0644]

index 251fed91abf35917d41e044431930a26fc33e523..2b68ac42ba81074f04f4b29c71fdc43f004fdc28 100644 (file)
@@ -183,21 +183,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
        constexpr
        span(type_identity_t<element_type> (&__arr)[_ArrayExtent]) noexcept
-       : span(static_cast<pointer>(__arr), _ArrayExtent)
+       : _M_ptr(__arr), _M_extent(_ArrayExtent)
        { }
 
       template<typename _Tp, size_t _ArrayExtent>
        requires __is_compatible_array<_Tp, _ArrayExtent>::value
        constexpr
        span(array<_Tp, _ArrayExtent>& __arr) noexcept
-       : span(static_cast<pointer>(__arr.data()), _ArrayExtent)
+       : _M_ptr(__arr.data()), _M_extent(_ArrayExtent)
        { }
 
       template<typename _Tp, size_t _ArrayExtent>
        requires __is_compatible_array<const _Tp, _ArrayExtent>::value
        constexpr
        span(const array<_Tp, _ArrayExtent>& __arr) noexcept
-       : span(static_cast<pointer>(__arr.data()), _ArrayExtent)
+       : _M_ptr(__arr.data()), _M_extent(_ArrayExtent)
        { }
 
       template<typename _Range>
@@ -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 (file)
index 0000000..8bbb5ca
--- /dev/null
@@ -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 <array>
+#include <span>
+
+struct A {
+  constexpr A(std::span<const unsigned char>) {}
+};
+constexpr A val{std::array<unsigned char, 2>{0x11, 0x22}};