On 3/25/19 12:02 PM, Marek Polacek wrote:
On Fri, Mar 22, 2019 at 04:20:43PM -0400, Jason Merrill wrote:
On 3/22/19 4:12 PM, Jason Merrill wrote:
On 3/22/19 2:14 PM, Marek Polacek wrote:
On Fri, Mar 22, 2019 at 10:48:32AM -0400, Jason Merrill wrote:

+  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.

Are you sure?  clang/icc/gcc8/msvc compile it.  I thought this was a
case of
aggregate initialization, where we have a nested braced-init-list:
http://eel.is/c++draft/dcl.init.aggr#4.2
"If an initializer is itself an initializer list, the element is
list-initialized, which will result in a recursive application of
the rules in
this subclause if the element is an aggregate."

Yes.  Since the first element of the outer init-list is also an
init-list, we initialize the first element of D from the inner
init-list.  The first element of D is the B base, so we're initializing
a B from {D{42}}.

Ah, and D is derived from B, so the B base is copy-initialized from the
(B base subobject of) the D temporary.  So that's why it's different for
a base class.

So originally, when calling reshape_init, we have

   {{ TARGET_EXPR<> }} of type D

we recurse on it -- it's a class so we call reshape_init_class.
Then we call
reshape_init_r on a field D.2070 for the base (type B), the ctor is
{ TARGET_EXPR<> }.
Here we elide the braces, so we return just the TARGET_EXPR as a
field_init
for D.2070, but then we're back in reshape_init_class and append the
TARGET_EXPR to new_init constructor:
5969       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
field, field_init);
so we end up with the undesirable form.

I don't think it's undesirable; the temporary initializes the base, not
the complete object.  It seems that the assert in digest_init_r is wrong
for C++17.

It seems a bit questionable that adding a layer of braces silently
causes slicing; I'll raise this with the committee.

Thanks for that.

I think let's warn instead of aborting if the first element of the aggregate
is a base class.

Okay.  I guess we might raise it to an error later, if it becomes invalid.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2019-03-25  Marek Polacek  <pola...@redhat.com>

        PR c++/89214 - ICE when initializing aggregates with bases.
        * typeck2.c (digest_init_r): Warn about object slicing instead of
        crashing.

OK.

Jason

Reply via email to