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