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