https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120397
Bug ID: 120397
Summary: std::uninitialized_value_construct cannot create
arrays of non-trivially destructible types
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: rejects-valid
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
#include <memory>
struct X { ~X() { } };
void f()
{
X x[1];
x->~X();
std::uninitialized_value_construct(&x, &x+1);
x->~X();
std::uninitialized_value_construct_n(&x, 1);
}
include/c++/15.1.0/bits/stl_construct.h:166:19: error: request for member '~X
[1]' in '* __pointer', which is of non-class type 'X [1]'
166 | __pointer->~_Tp();
| ~~~~~~~~~~~~^~~
The standard just says that constructed elements need to be destroyed if an
exception happens, it doesn't say how. We call std::_Destroy(first, cur) to
destroy them, but that can't handle arrays in C++17 (for C++20 it calls
std::destroy_at which does handle arrays).
This is related to Bug 94831 but this time for types with non-trivial
destructors, so that std::_Destroy isn't a no-op.
We could either stop using std::_Destroy(first, cur) in the uninitialized algos
(no thanks), or make std::_Destroy(first, cur) handle arrays, or make
std::_Destroy(*first) handle arrays.
The latter would be consistent with std::destroy_at, and would mean that
std::_Destroy_n(first, n) would also work for arrays. But to make the code
above (and all similar cases?) work it's sufficient to handle it in
std::_Destroy(first, last). All the uninitialized algos use that.