[C++ PATCH] Fix ICE in reshape_init_class (PR c++/84874)

Jason Merrill jason@redhat.com
Fri Mar 16 05:09:00 GMT 2018


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



More information about the Gcc-patches mailing list