https://gcc.gnu.org/g:82d2d12da93b5afbc3479e64d0aa0dcec5b42d8d
commit r16-2154-g82d2d12da93b5afbc3479e64d0aa0dcec5b42d8d Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Jul 8 10:48:21 2025 +0100 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. Diff: --- libstdc++-v3/include/bits/stl_uninitialized.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 3a37ddc71ba1..351c3a17457f 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -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