On Tue, Sep 09, 2025 at 04:52:08PM +0200, Jason Merrill wrote: > > I'll try to work on this next, but it won't be trivial. The forward gotos > > and switch cases are one thing and backward gotos another one, both need > > to be handled differently, plus make it work properly with [[fallthrough]] > > etc. (I'm contemplating on marking the if (0) { } around the extra labels > > and perhaps moved case labels with some flag so that gimplification can > > see it has been added artificially). > > True, the above transformation works for switch or goto from outside the > scope of 't', but from within the scope of 't' you want them to jump to > 'skip'. We would need check_previous_goto to be able to fix up a previous > goto to jump to the right label.
Yeah. I've been thinking about changing the order of check_goto (destination); add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN)); return add_stmt (build_stmt (input_location, GOTO_EXPR, destination)); to only call check_goto after build_stmt and pass it as a new argument &TREE_OPERAND (goto_stmt, 0). Then we'd need to bother to add that tree * (if !computed, I think for computed gotos we just should handle it as UB instead of EB, we can't do better than that) even in the /* Don't bother creating another use if the last goto had the same data, and will therefore create the same set of errors. */ if (ent->uses && ent->uses->names_in_scope == current_binding_level->names) return; case (push to some vector) and on check_previous_goto_1 then deal with it, perhaps with the help of walking back the stmts of the current stmt list, skipping over labels/case labels and emitting or amending the magic marked if (0) IF_STMT there to add further labels depending on which set of vars need to be .DEFERRED_INIT initialized. For the backward jumps, it will need to be handled some other way, but with check_goto having the address it could resolve it right away and modify what the address points to. Jakub