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.