This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH for c++/89214 - ICE when initializing aggregates with bases


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.

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

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]