Hi! As the testcase shows, even when we've already reshaped the initializer, if it uses designated initializers and skips using those over others, we can have field != d->cur->index. The following patch handles that case.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-03-15 Jakub Jelinek <ja...@redhat.com> PR c++/84874 * decl.c (reshape_init_class): Don't assert d->cur->index == field if d->cur->index is a FIELD_DECL, instead set field to d->cur->index. * g++.dg/cpp2a/desig7.C: New test. --- gcc/cp/decl.c.jj 2018-03-15 18:44:21.662300888 +0100 +++ gcc/cp/decl.c 2018-03-15 19:55:54.831039431 +0100 @@ -5885,8 +5885,17 @@ reshape_init_class (tree type, reshape_i return error_mark_node; if (TREE_CODE (d->cur->index) == FIELD_DECL) - /* We already reshaped this. */ - gcc_assert (d->cur->index == field); + { + /* We already reshaped this. */ + if (field != d->cur->index) + { + tree id = DECL_NAME (d->cur->index); + gcc_assert (id); + gcc_checking_assert (d->cur->index + == get_class_binding (type, id, false)); + field = d->cur->index; + } + } else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE) field = get_class_binding (type, d->cur->index, false); else --- gcc/testsuite/g++.dg/cpp2a/desig7.C.jj 2018-03-15 19:54:47.060017400 +0100 +++ gcc/testsuite/g++.dg/cpp2a/desig7.C 2018-03-15 19:54:47.060017400 +0100 @@ -0,0 +1,31 @@ +// PR c++/84874 +// { dg-do run { target c++11 } } +// { dg-options "" } + +struct A { int a, b; }; +struct B { A d; }; + +void +foo (B *x) +{ + *x = { .d = { .b = 5 } }; +} + +void +bar (A *x) +{ + *x = { .b = 6 }; +} + +int +main () +{ + B b = { { 2, 3 } }; + foo (&b); + if (b.d.a != 0 || b.d.b != 5) + __builtin_abort (); + b.d.a = 8; + bar (&b.d); + if (b.d.a != 0 || b.d.b != 6) + __builtin_abort (); +} Jakub