On 11/18/21 6:56 PM, Jason Merrill via Gcc-patches wrote:
On 11/18/21 19:24, Marek Polacek wrote:
On Thu, Nov 18, 2021 at 05:10:47PM -0500, Jason Merrill wrote:
On 11/8/21 18:41, Marek Polacek wrote:
@@ -1311,13 +1462,25 @@ emit_mem_initializers (tree mem_inits)
if (!COMPLETE_TYPE_P (current_class_type))
return;
+ /* Keep a set holding fields that are not initialized. */
+ hash_set<tree> uninitialized;
+
+ /* Initially that is all of them. */
+ if (warn_uninitialized)
+ for (tree f = next_initializable_field (TYPE_FIELDS
(current_class_type));
+ f != NULL_TREE;
+ f = next_initializable_field (DECL_CHAIN (f)))
+ if (!DECL_ARTIFICIAL (f))
+ uninitialized.add (f);
I wonder about flipping the sense of the set, so that it tracks
fields that
have been initialized rather than those that haven't; then you
wouldn't need
this loop.
True, but then I'd have to figure out a new way to signal that we
don't want
to warn about the current member-initializer-list. What I mean by
that is
that when I see e.g. a MODIFY_EXPR or something else with side-effects in
a mem-init, I can just empty the set:
case MODIFY_EXPR:
/* Don't attempt to handle statement-expressions, either. */
case STATEMENT_LIST:
uninitialized->empty ();
and then we won't even bother walking the other mem-inits, because
find_uninit_fields has:
if (!uninitialized->is_empty ())
{
// walk_tree ()
}
and I thought that was pretty elegant. Of course, I could just add a new
bool member into find_uninit_data and then do what you suggest... Up to
you, I'm happy to do that too.
No need, the patch is OK as is.
Awesome! Thank you both and especially Marek for finally making
it happen (after no less than 15 years)! :)
Martin
Jason