https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90254
Bug ID: 90254
Summary: ice on aggregate initialization of unmovable base
Product: gcc
Version: 8.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: leni536 at gmail dot com
Target Milestone: ---
The compiler bumps into an internal compiler error on the following, valid
code:
//aggregate base class
struct A1 {
A1() = default;
A1(const A1&) = delete;
A1(A1&&) = delete;
};
//non-aggregate base class
struct A2 {
A2() {};
A2(const A2&) = delete;
A2(A2&&) = delete;
};
//aggregate derived classes
struct B1 : A1 {};
struct B2 : A2 {};
A1 f1() {
return A1();
}
A2 f2() {
return A2();
}
int main() {
A1 a1{f1()}; // OK
B1 b1_1{{}}; // OK
B1 b1_2{A1{}}; // OK
B1 b1_3{A1()}; // OK
B1 b1_4{f1()}; // ICE
A2 a2{f2()}; // OK
B2 b2_1{{}}; // OK
B2 b2_2{A2{}}; // OK
B2 b2_3{A2()}; // OK
B2 b2_4{f2()}; // ICE
}
It is valid because each element of the aggregate is copy-initialized from the
corresponding initializer-clause. If it is a prvalue then no temporary is
materialized.
Some argue that this is a defect in the standard and the code above should be
rejected:
https://bugs.llvm.org/show_bug.cgi?id=34516