mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libstdc++: Do not use list-initialization in std::span members [PR120997]
As the bug report shows, for span<const bool> the return statements of
the form `return {data(), count};` will use the new C++26 constructor,
span(initializer_list<element_type>).
Although the conversions from data() to bool and count to bool are
narrowing and should be ill-formed, in system headers the narrowing
diagnostics are suppressed. In any case, even if the compiler diagnosed
them as ill-formed, we still don't want the initializer_list constructor
to be used. We want to use the span(element_type*, size_t) constructor
instead.
Replace the braced-init-list uses with S(data(), count) where S is the
correct return type. We need to make similar changes in the C++26
working draft, which will be taken care of via an LWG issue.
libstdc++-v3/ChangeLog:
PR libstdc++/120997
* include/std/span (span::first, span::last, span::subspan): Do
not use braced-init-list for return statements.
* testsuite/23_containers/span/120997.cc: New test.
This commit is contained in:
committed by
Jonathan Wakely
parent
82dd19890b
commit
a72d0e1a8b
@@ -376,7 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
else
|
||||
static_assert(_Count <= extent);
|
||||
using _Sp = span<element_type, _Count>;
|
||||
return _Sp{ _SizedPtr{this->data()} };
|
||||
return _Sp(_SizedPtr{this->data()});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -384,7 +384,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
first(size_type __count) const noexcept
|
||||
{
|
||||
__glibcxx_assert(__count <= size());
|
||||
return { this->data(), __count };
|
||||
return span<element_type>(this->data(), __count);
|
||||
}
|
||||
|
||||
template<size_t _Count>
|
||||
@@ -397,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
else
|
||||
static_assert(_Count <= extent);
|
||||
using _Sp = span<element_type, _Count>;
|
||||
return _Sp{ _SizedPtr{this->data() + (this->size() - _Count)} };
|
||||
return _Sp(_SizedPtr{this->data() + (this->size() - _Count)});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -405,7 +405,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
last(size_type __count) const noexcept
|
||||
{
|
||||
__glibcxx_assert(__count <= size());
|
||||
return { this->data() + (this->size() - __count), __count };
|
||||
return span<element_type>(this->data() + (this->size() - __count),
|
||||
__count);
|
||||
}
|
||||
|
||||
template<size_t _Offset, size_t _Count = dynamic_extent>
|
||||
@@ -424,7 +425,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using _Sp = span<element_type, _S_subspan_extent<_Offset, _Count>()>;
|
||||
|
||||
if constexpr (_Count == dynamic_extent)
|
||||
return _Sp{ this->data() + _Offset, this->size() - _Offset };
|
||||
return _Sp(this->data() + _Offset, this->size() - _Offset);
|
||||
else
|
||||
{
|
||||
if constexpr (_Extent == dynamic_extent)
|
||||
@@ -437,7 +438,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
static_assert(_Count <= extent);
|
||||
static_assert(_Count <= (extent - _Offset));
|
||||
}
|
||||
return _Sp{ _SizedPtr{this->data() + _Offset} };
|
||||
return _Sp(_SizedPtr{this->data() + _Offset});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__count <= size());
|
||||
__glibcxx_assert(__offset + __count <= size());
|
||||
}
|
||||
return {this->data() + __offset, __count};
|
||||
return span<element_type>(this->data() + __offset, __count);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
46
libstdc++-v3/testsuite/23_containers/span/120997.cc
Normal file
46
libstdc++-v3/testsuite/23_containers/span/120997.cc
Normal file
@@ -0,0 +1,46 @@
|
||||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <span>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test_first()
|
||||
{
|
||||
bool arr[5];
|
||||
std::span<const bool> s(arr);
|
||||
std::span<const bool> s2 = s.first(5);
|
||||
VERIFY( s2.data() == s.data() );
|
||||
std::span<const bool> s3 = s.first<5>();
|
||||
VERIFY( s3.data() == s.data() );
|
||||
}
|
||||
|
||||
void
|
||||
test_last()
|
||||
{
|
||||
bool arr[5];
|
||||
std::span<const bool> s(arr);
|
||||
std::span<const bool> s2 = s.last(5);
|
||||
VERIFY( s2.data() == s.data() );
|
||||
std::span<const bool> s3 = s.last<5>();
|
||||
VERIFY( s3.data() == s.data() );
|
||||
}
|
||||
|
||||
void
|
||||
test_subspan()
|
||||
{
|
||||
bool arr[5];
|
||||
std::span<const bool> s(arr);
|
||||
std::span<const bool> s2 = s.subspan(0, 5);
|
||||
VERIFY( s2.data() == s.data() );
|
||||
std::span<const bool> s3 = s.subspan<0>();
|
||||
VERIFY( s3.data() == s.data() );
|
||||
std::span<const bool> s4 = s.subspan<0, 5>();
|
||||
VERIFY( s4.data() == s.data() );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_first();
|
||||
test_last();
|
||||
test_subspan();
|
||||
}
|
||||
Reference in New Issue
Block a user