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.

Reply via email to