https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123579
Bug ID: 123579
Summary: Compiler generated copy constructors use copy
initialization instead of direct initialization
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: mwinkler at blizzard dot com
Target Milestone: ---
Created attachment 63339
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=63339&action=edit
bug reproduction cpp
https://eel.is/c++draft/class.copy.ctor#14
https://godbolt.org/z/oq6csz9se
```
#include <new>
#include <cstddef>
namespace stl
{
template<class T, size_t N>
struct array
{
T _elements[N];
};
}
struct Foo
{
explicit Foo(const Foo& _other);
};
struct Bar
{
Bar(const Bar& _other) = default;
stl::array<Foo, 1> a;
};
struct Data
{
alignas(alignof(Bar)) char transfers[sizeof(Bar)];
};
void CopyUninit(Data& x, const Data& _other)
{
::new(static_cast<void*>(reinterpret_cast<Bar*>(&x.transfers)))
Bar(*reinterpret_cast<const Bar*>(&_other.transfers[0]));
}
```
The compiler generated copy constructor for `stl::array` above appears to use
copy initialization which does not take into account explicit constructors
leading to `Foo(const Foo&)` candidate being ignored.
According to the standard the compiler generated copy constructor should be
using direct initialization so `Foo(const Foo&)` is a viable candidate.