mirror of git://gcc.gnu.org/git/gcc.git
libstdc++: Fix __uninitialized_default for constexpr case
We should not use the std::fill optimization for trivial types during
constant evaluation, because we need to begin the lifetime of all
objects, even trivially default constructible ones.
This fixes a bug that Clang diagnosed:
include/c++/16.0.0/bits/stl_algobase.h:925:11: note: assignment to object outside its lifetime is not allowed in a constant expression
925 | *__first = __val;
| ~~~~~~~~~^~~~~~~
I initially just added the #ifdef __cpp_lib_is_constant_evaluated check,
but that gave warnings with GCC because the function isn't constexpr
until C++26. So then I tried checking __glibcxx_raw_memory_algorithms
for the value indicating constexpr uninitialized_value_construct, but
that macro depends on __cpp_constexpr >= 202406 and Clang 19 doesn't
support constexpr placement new, so doesn't define it.
So I decided to just change __uninitialized_default to use
_GLIBCXX20_CONSTEXPR which is consistent with __uninitialized_default_n
(which needs to be constexpr because it's used by std::vector). We don't
currently need to use __uninitialized_default in constexpr contexts for
C++20 code, but we might find uses for it, so now it would be possible.
libstdc++-v3/ChangeLog:
* include/bits/stl_uninitialized.h (__uninitialized_default):
Do not use optimized implementation for constexpr case. Use
_GLIBCXX20_CONSTEXPR instead of _GLIBCXX26_CONSTEXPR.
This commit is contained in:
parent
4d24612a2e
commit
82d2d12da9
|
|
@ -922,11 +922,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
// __uninitialized_default
|
||||
// Fills [first, last) with value-initialized value_types.
|
||||
template<typename _ForwardIterator>
|
||||
_GLIBCXX26_CONSTEXPR
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
inline void
|
||||
__uninitialized_default(_ForwardIterator __first,
|
||||
_ForwardIterator __last)
|
||||
{
|
||||
#ifdef __cpp_lib_is_constant_evaluated
|
||||
if (std::is_constant_evaluated())
|
||||
return __uninitialized_default_1<false>::
|
||||
__uninit_default(__first, __last);
|
||||
#endif
|
||||
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type
|
||||
_ValueType;
|
||||
// trivial types can have deleted assignment
|
||||
|
|
|
|||
Loading…
Reference in New Issue