On 3/21/19 4:51 PM, Marek Polacek wrote:
This is a crash in digest_init_r -- we encounter

   /* "If T is a class type and the initializer list has a single
      element of type cv U, where U is T or a class derived from T,
      the object is initialized from that element."  */
   if (flag_checking
       && cxx_dialect >= cxx11
       && BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
       && CONSTRUCTOR_NELTS (stripped_init) == 1
       && ((CLASS_TYPE_P (type) && !CLASSTYPE_NON_AGGREGATE (type))
           || VECTOR_TYPE_P (type)))
     {
       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 ();
     }

As the comment suggests, we have code to fix this up in reshape_init_r:

   /* "If T is a class type and the initializer list has a single element of
      type cv U, where U is T or a class derived from T, the object is
      initialized from that element."  Even if T is an aggregate.  */
   if (cxx_dialect >= cxx11 && (CLASS_TYPE_P (type) || VECTOR_TYPE_P (type))
       && first_initializer_p
       && d->end - d->cur == 1
       && reference_related_p (type, TREE_TYPE (init)))
     {
       d->cur++;
       return init;
     }

but in this case this didn't work, because reshape_init_class always creates
a fresh CONSTRUCTOR.

But we hit that code before reshape_init_class, why didn't it work?

As of C++17, aggregates can have bases

Does it matter whether BB is a base or a member?

+  B b10 = {{B{42}}};
+  B b11 = {{B{{42}}}};
+  B b12 = {{B{{{42}}}}};

These look ill-formed to me: too many braces around the B value.

Looks like the original testcase had the same problem. So I think this is ice-on-invalid.

Jason

Reply via email to