This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix ICE in reshape_init_class (PR c++/84874)
- From: Jason Merrill <jason at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 15 Mar 2018 22:38:52 -0400
- Subject: Re: [C++ PATCH] Fix ICE in reshape_init_class (PR c++/84874)
- References: <20180315232958.GZ8577@tucnak>
OK.
On Thu, Mar 15, 2018 at 7:29 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> 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 <jakub@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