On 9/23/25 7:24 PM, Jakub Jelinek wrote:
On Tue, Sep 23, 2025 at 12:22:01PM +0100, Jason Merrill wrote:
I notice this doesn't skip empty types, which could use a comment.  I guess
if we're only doing this for the outermost object it isn't a problem to
clobber empty types, but is it useful to clobber them when there's no data
anyway?

That was the idea that it can be done for those anyway, but you're right,
it isn't useful for those.

+static tree
+adjust_backward_gotos (tree *tp, int *walk_subtrees, void *data)
+{
+  tree t = *tp;
+  switch (TREE_CODE (t))
+    {
+    case LABEL_EXPR:
+      if (DECL_NAME (LABEL_EXPR_LABEL (t)))
+       {
+         named_label_entry *ent
+           = lookup_label_1 (DECL_NAME (LABEL_EXPR_LABEL (t)), false);
+         if (ent->direct_goto)
+           {
+             *tp = alloc_stmt_list ();
+             append_to_statement_list_force (t, tp);
+             adjust_backward_goto (ent, tsi_last (*tp));
+           }
+       }
+      *walk_subtrees = 0;
+      break;
+    case STATEMENT_LIST:

Handling STATEMENT_LIST specially is an optimization to avoid the
alloc_stmt_list above, right?  Seems worth a comment.

It isn't just an optimization, without that I couldn't search for the
previous artificial if (0) with the new flag in the same STATEMENT_LIST
but would need to look through nested STATEMENT_LISTs etc.
The STATEMENT_LIST case is the common case, the LABEL_EXPR is for the
rare case where there is say if (1) lab:; and the code first turns
it into a STATEMENT_LIST containing just the LABEL_EXPR and then handles it
like the normal case.  Added comments.

+static tree
+maybe_add_deferred_init_calls (tree_stmt_iterator iter, tree case_label,
+                              tree *decls, unsigned ndecls)

The logic in this function could use more comments.

Added comments too.

+             while (!tsi_end_p (iter)
+                    && (TREE_CODE (tsi_stmt (iter)) == LABEL_EXPR
+                        || (TREE_CODE (tsi_stmt (iter)) == CASE_LABEL_EXPR
+                            && !case_label)))
+               tsi_prev (&iter);

Why is this loop inside the loop over the decls?  Ah, in case we have labels
between groups of inits?

Yes.  In that case and if we have more decls we just need to skip over them,
only when we come to the end of decls the code searches for a LABEL_EXPR
among those (or moves CASE_LABEL_EXPR).

OK with the added comments.

Here is a new version of the patch.  Tested on top of current trunk,
so including your new changes (but not the just posted and not committed
one, though that didn't change anything on the problematic regressions).
Changes since last time:
1) used the "clobber *this" attribute way to fix up the
    Wuninitialized-10.C Wuninitialized-pr111123-1.C regressions, but unlike
    to the untested incremental patch I've posted earlier today, had to
    also tweak the fnsplit pass to remove the attribute, because when
    fnsplit splits a constructor and the inlined part initializes some
    members in *this and the outlined part would have the attribute, we'd
    get bogus warnings
2) dealt with Warray-bounds-20.C which has same amount of diagnostics
    as before, just on different lines (and both old and new are reasonable)
3) filed PR122044 and xfailed/skipped 2 analyzer tests for c++26 until
    that is fixed
4) for the older PR121975 OpenACC PR skipped various affected tests
    until that is fixed

Bootstrapped/regtested on x86_64-linux and i686-linux, no regressions
in the testsuite, ok for trunk?

...
@@ -2489,26 +2497,38 @@ last_stmt_in_scope (gimple *stmt)
    if (!stmt)
      return NULL;
+ auto last_stmt_in_seq = [] (gimple_seq s) {

Open brace should go on the next line, as with the other lambda in the patch.

OK with that fixed.

Jason

Reply via email to