PR c++/89214 - ICE when initializing aggregates with bases.
* typeck2.c (digest_init_r): Warn about object slicing instead of crashing. * g++.dg/cpp1z/aggr-base8.C: New test. * g++.dg/cpp1z/aggr-base9.C: New test. From-SVN: r269919
This commit is contained in:
parent
a55f758221
commit
bf8c1b11d5
5 changed files with 112 additions and 2 deletions
|
@ -1,5 +1,9 @@
|
|||
2019-03-25 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/89214 - ICE when initializing aggregates with bases.
|
||||
* typeck2.c (digest_init_r): Warn about object slicing instead of
|
||||
crashing.
|
||||
|
||||
PR c++/89705 - ICE with reference binding with conversion function.
|
||||
* call.c (reference_binding): If the result of the conversion function
|
||||
is a prvalue of non-class type, use the cv-unqualified type.
|
||||
|
|
|
@ -1209,8 +1209,29 @@ digest_init_r (tree type, tree init, int nested, int flags,
|
|||
{
|
||||
tree elt = CONSTRUCTOR_ELT (stripped_init, 0)->value;
|
||||
if (reference_related_p (type, TREE_TYPE (elt)))
|
||||
/* We should have fixed this in reshape_init. */
|
||||
gcc_unreachable ();
|
||||
{
|
||||
/* In C++17, aggregates can have bases, thus participate in
|
||||
aggregate initialization. In the following case:
|
||||
|
||||
struct B { int c; };
|
||||
struct D : B { };
|
||||
D d{{D{{42}}}};
|
||||
|
||||
there's an extra set of braces, so the D temporary initializes
|
||||
the first element of d, which is the B base subobject. The base
|
||||
of type B is copy-initialized from the D temporary, causing
|
||||
object slicing. */
|
||||
tree field = next_initializable_field (TYPE_FIELDS (type));
|
||||
if (field && DECL_FIELD_IS_BASE (field))
|
||||
{
|
||||
if (warning_at (loc, 0, "initializing a base class of type %qT "
|
||||
"results in object slicing", TREE_TYPE (field)))
|
||||
inform (loc, "remove %<{ }%> around initializer");
|
||||
}
|
||||
else
|
||||
/* We should have fixed this in reshape_init. */
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
2019-03-25 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/89214 - ICE when initializing aggregates with bases.
|
||||
* g++.dg/cpp1z/aggr-base8.C: New test.
|
||||
* g++.dg/cpp1z/aggr-base9.C: New test.
|
||||
|
||||
PR c++/89705 - ICE with reference binding with conversion function.
|
||||
* g++.dg/cpp0x/rv-conv2.C: New test.
|
||||
|
||||
|
|
48
gcc/testsuite/g++.dg/cpp1z/aggr-base8.C
Normal file
48
gcc/testsuite/g++.dg/cpp1z/aggr-base8.C
Normal file
|
@ -0,0 +1,48 @@
|
|||
// PR c++/89214
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
struct A
|
||||
{
|
||||
A (int);
|
||||
};
|
||||
|
||||
struct BB
|
||||
{
|
||||
A a;
|
||||
};
|
||||
|
||||
struct B : BB
|
||||
{
|
||||
};
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
B b1 = {42};
|
||||
B b2 = {{42}};
|
||||
B b3 = {{{42}}};
|
||||
|
||||
B b4 = B{42};
|
||||
B b5 = B{{42}};
|
||||
B b6 = B{{{42}}};
|
||||
|
||||
B b7 = {B{42}};
|
||||
B b8 = {B{{42}}};
|
||||
B b9 = {B{{{42}}}};
|
||||
|
||||
B b10 = {{B{42}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" }
|
||||
B b11 = {{B{{42}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" }
|
||||
B b12 = {{B{{{42}}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" }
|
||||
|
||||
B bb1{42};
|
||||
B bb2{{42}};
|
||||
B bb3{{{42}}};
|
||||
|
||||
B bb7{B{42}};
|
||||
B bb8{B{{42}}};
|
||||
B bb9{B{{{42}}}};
|
||||
|
||||
B bb10{{B{42}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" }
|
||||
B bb11{{B{{42}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" }
|
||||
B bb12{{B{{{42}}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" }
|
||||
}
|
33
gcc/testsuite/g++.dg/cpp1z/aggr-base9.C
Normal file
33
gcc/testsuite/g++.dg/cpp1z/aggr-base9.C
Normal file
|
@ -0,0 +1,33 @@
|
|||
// PR c++/89214
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
struct B {
|
||||
int c;
|
||||
};
|
||||
|
||||
struct D : B { };
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
D d1 = {42};
|
||||
D d2 = {{42}};
|
||||
|
||||
D d4 = D{42};
|
||||
D d5 = D{{42}};
|
||||
|
||||
D d7 = {D{42}};
|
||||
D d8 = {D{{42}}};
|
||||
|
||||
D d10 = {{D{42}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" }
|
||||
D d11 = {{D{{42}}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" }
|
||||
|
||||
D dd1{42};
|
||||
D dd2{{42}};
|
||||
|
||||
D dd7{D{42}};
|
||||
D dd8{D{{42}}};
|
||||
|
||||
D dd10{{D{42}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" }
|
||||
D dd11{{D{{42}}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" }
|
||||
}
|
Loading…
Add table
Reference in a new issue