On Sun, Nov 24, 2019 at 12:24:48PM -0500, Jason Merrill wrote:
> On 11/16/19 5:23 PM, Marek Polacek wrote:
> > [ Working virtually on Baker Island. ]
> > 
> > This patch implements C++20 P1331, allowing trivial default initialization 
> > in
> > constexpr contexts.
> > 
> > I used Jakub's patch from the PR which allowed uninitialized variables in
> > constexpr contexts.  But the hard part was handling CONSTRUCTOR_NO_CLEARING
> > which is always cleared in cxx_eval_call_expression.  We need to set it in
> > the case a constexpr constructor doesn't initialize all the members, so that
> > we can give proper diagnostic instead of value-initializing.  A lot of my
> > attempts flopped but then I came up with this approach, which handles 
> > various
> > cases as tested in constexpr-init8.C, where S is initialized by a 
> > non-default
> > constexpr constructor, and constexpr-init9.C, using delegating constructors.
> > And the best part is that I didn't need any new cx_check_missing_mem_inits
> > calls!  Just save the information whether a constructor is missing an init
> > into constexpr_fundef_table and retrieve it when needed.
> 
> Is it necessary to clear the flag for constructors that do happen to
> initialize all the members?  I would think that leaving that clearing to
> reduced_constant_expression_p would be enough.

It seems so: if I tweak cxx_eval_call_expression to only call 
clear_no_implicit_zero
when 'fun' isn't DECL_CONSTRUCTOR_P, then a lot breaks, e.g. constexpr-base.C
where the constructor initializes all the members.  By breaking I mean spurious
errors coming from

5937   if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
5938     {
5939       if (!allow_non_constant)
5940         error ("%qE is not a constant expression because it refers to "
5941                "an incompletely initialized variable", t);
5942       TREE_CONSTANT (r) = false;
5943       non_constant_p = true;
5944     }

> > constexpr-init10.C demonstrates that we can now elide a constructor call,
> > this is caused by the walk_field_subobs hunk.  I hope that's OK.
> 
> So long as the object's vptr is initialized properly, absolutely.  Since a
> has static storage duration, constant zero-initialization plus the default
> constructor fully initialize the object.

Ah, that's comforting to hear, thanks.

--
Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA

Reply via email to