c++: Fix ICE in reshape_init with init-list [PR95164]
This patch fixes a long-standing bug in reshape_init_r. Since r209314 we implement DR 1467 which handles list-initialization with a single initializer of the same type as the target. In this test this causes a crash in reshape_init_r when we're processing a constructor that has undergone the DR 1467 transformation. Take e.g. the foo({{1, {H{k}}}}); line in the attached test. {H{k}} initializes the field b of H in I. H{k} is a functional cast, so has TREE_HAS_CONSTRUCTOR set, so is COMPOUND_LITERAL_P. We perform the DR 1467 transformation and turn {H{k}} into H{k}. Then we attempt to reshape H{k} again and since first_initializer_p is null and it's COMPOUND_LITERAL_P, we go here: else if (COMPOUND_LITERAL_P (stripped_init)) gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init)); then complain about the missing braces, go to reshape_init_class and ICE on gcc_checking_assert (d->cur->index == get_class_binding (type, id)); because due to the missing { } we're looking for 'b' in H, but that's not found. So we have to be prepared to handle an initializer whose outer braces have been removed due to DR 1467. gcc/cp/ChangeLog: PR c++/95164 * decl.c (reshape_init_r): When initializing an aggregate member with an initializer from an initializer-list, also consider COMPOUND_LITERAL_P. gcc/testsuite/ChangeLog: PR c++/95164 * g++.dg/cpp0x/initlist123.C: New test.
This commit is contained in:
parent
1690a839cf
commit
acbe30bbc8
2 changed files with 40 additions and 1 deletions
|
@ -6466,7 +6466,7 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
|
|||
non-empty subaggregate, brace elision is assumed and the
|
||||
initializer is considered for the initialization of the first
|
||||
member of the subaggregate. */
|
||||
if (TREE_CODE (init) != CONSTRUCTOR
|
||||
if ((TREE_CODE (init) != CONSTRUCTOR || COMPOUND_LITERAL_P (init))
|
||||
/* But don't try this for the first initializer, since that would be
|
||||
looking through the outermost braces; A a2 = { a1 }; is not a
|
||||
valid aggregate initialization. */
|
||||
|
|
39
gcc/testsuite/g++.dg/cpp0x/initlist123.C
Normal file
39
gcc/testsuite/g++.dg/cpp0x/initlist123.C
Normal file
|
@ -0,0 +1,39 @@
|
|||
// PR c++/95164
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-Wmissing-braces" }
|
||||
|
||||
struct H {
|
||||
int a;
|
||||
};
|
||||
|
||||
struct X : H { };
|
||||
|
||||
struct I {
|
||||
int c;
|
||||
H b;
|
||||
};
|
||||
struct E { I d; };
|
||||
void foo(E);
|
||||
|
||||
template<int N>
|
||||
void fn ()
|
||||
{
|
||||
int a = 42;
|
||||
int &k = a;
|
||||
|
||||
foo({1, {H{k}}}); // { dg-warning "missing braces around initializer for .I." }
|
||||
foo({1, {X{k}}}); // { dg-warning "missing braces around initializer for .I." }
|
||||
|
||||
foo({{1, {k}}});
|
||||
foo({{1, {N}}});
|
||||
|
||||
foo({{1, H{k}}});
|
||||
foo({{1, H{N}}});
|
||||
foo({{1, X{k}}});
|
||||
foo({{1, X{N}}});
|
||||
|
||||
foo({{1, {H{k}}}});
|
||||
foo({{1, {H{N}}}});
|
||||
foo({{1, {X{k}}}});
|
||||
foo({{1, {X{N}}}});
|
||||
}
|
Loading…
Add table
Reference in a new issue