https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106608
--- Comment #7 from Jonathan Wakely ---
(In reply to Egor Pugin from comment #1)
> All major compilers (MSVC, GCC, Clang) of all (tried) modern versions (in
> case of GCC — before 12) build this code without problems. Is this a GCC
> regression?
Your links clearly show you're compiling with Clang though, not GCC. The paste
starts with:
[1/135] /usr/lib/ccache/bin/clang++
The code can be reduced to:
template
struct vector
{
T* ptr;
vector();
vector(const vector&);
~vector() { ++ptr; } // requires T to be complete
};
struct nullopt_t { };
constexpr nullopt_t nullopt{};
template
struct optional_payload
{
optional_payload() = default;
~optional_payload() { if (engaged) value.~T(); }
union {
unsigned char dummy;
T value;
};
bool engaged = false;
};
template
struct optional_base
{
optional_base() = default;
~optional_base() = default;
optional_payload payload;
};
template
struct optional : optional_base
{
constexpr optional(nullopt_t) { }
};
struct ScanInfo;
struct List {
List(optional>&& = nullopt);
};
GCC compiles this, but Clang doesn't:
$ clang++ -std=c++17 -c inc.cc
inc.cc:36:13: error: call to implicitly-deleted default constructor of
'optional_base>'
constexpr optional(nullopt_t) { }
^
inc.cc:47:39: note: in instantiation of member function
'optional>::optional' requested here
List(optional>&& = nullopt);
^
inc.cc:28:3: note: explicitly defaulted function was implicitly deleted here
optional_base() = default;
^
inc.cc:30:23: note: default constructor of 'optional_base>' is
implicitly deleted because field 'payload' has a deleted default constructor
optional_payload payload;
^
inc.cc:16:3: note: explicitly defaulted function was implicitly deleted here
optional_payload() = default;
^
inc.cc:20:7: note: default constructor of 'optional_payload>'
is implicitly deleted because variant field 'value' has a non-trivial default
constructor
T value;
^
1 error generated.
Neither does EDG:
$ edg --c++17 -c inc.cc
"inc.cc", line 36: error: the default constructor of
"optional_base>" cannot be referenced -- it is a
deleted function
constexpr optional(nullopt_t) { }
^
detected during instantiation of "optional::optional(nullopt_t)
[with T=vector]" at line 42
"inc.cc", line 7: error: expression must be a pointer to a complete object type
~vector() { ++ptr; } // requires T to be complete
^
detected during:
instantiation of "vector::~vector() [with T=ScanInfo]" at line
17
instantiation of "optional_payload::~optional_payload() [with
T=vector]" at line 43
2 errors detected in the compilation of "inc.cc".
Nor MSVC:
(7): error C2036: 'ScanInfo *': unknown size
(7): note: while compiling class template member function
'vector::~vector(void)'
(44): note: see reference to function template instantiation
'vector::~vector(void)' being compiled
(20): note: see reference to class template instantiation
'vector' being compiled
(30): note: see reference to class template instantiation
'optional_payload' being compiled
with
[
T=vector
]
(35): note: see reference to class template instantiation
'optional_base' being compiled
with
[
T=vector
]
(42): note: see reference to class template instantiation
'optional>' being compiled
Compiler returned: 2
Maybe the code is ill-formed (no diagnostic required), or maybe G++ is being
too generous to compile it, but I don't think there's a libstdc++ bug here.