]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Fix __uninitialized_default for constexpr case
authorJonathan Wakely <jwakely@redhat.com>
Tue, 8 Jul 2025 09:48:21 +0000 (10:48 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 9 Jul 2025 16:56:22 +0000 (17:56 +0100)
commit82d2d12da93b5afbc3479e64d0aa0dcec5b42d8d
treeef0ed0494dbc1c7da6669f8153d445dc27b80905
parent4d24612a2e453aa4755821a4d168bbc338a20036
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.
libstdc++-v3/include/bits/stl_uninitialized.h