From: Richard Biener Date: Mon, 3 Nov 2025 12:59:36 +0000 (+0100) Subject: Fix unsafe stmt modifications in FOR_EACH_IMM_USE_STMT X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b9457ed89cd84c609482a6d808e1bbdbe2cd84ac;p=thirdparty%2Fgcc.git Fix unsafe stmt modifications in FOR_EACH_IMM_USE_STMT The following fixes path isolation changing the immediate use list of an SSA name that is currently iterated over via FOR_EACH_IMM_USE_STMT. This happens when it duplicates a BB within this and creates/modifies stmts that contain SSA uses of the name and calls update_stmt which re-builds SSA operands, including removal of SSA uses and re-inserting them. This is not safe as that might cause missed iterated uses but more importantly could cause the 'next' use to be removed. For the case in question the fix is to collect interesting uses in a vec and do the processing outside of the FOR_EACH_IMM_USE_STMT iteration. * gimple-ssa-isolate-paths.cc (check_loadstore): Set the volatile flag on the stmt manually. (find_implicit_erroneous_behavior): Move code transform outside of FOR_EACH_IMM_USE_STMT iteration. --- diff --git a/gcc/gimple-ssa-isolate-paths.cc b/gcc/gimple-ssa-isolate-paths.cc index ca1daf1d168..ffa04d15052 100644 --- a/gcc/gimple-ssa-isolate-paths.cc +++ b/gcc/gimple-ssa-isolate-paths.cc @@ -56,7 +56,7 @@ check_loadstore (gimple *stmt, tree op, tree, void *data) { TREE_THIS_VOLATILE (op) = 1; TREE_SIDE_EFFECTS (op) = 1; - update_stmt (stmt); + gimple_set_has_volatile_ops (stmt, true); return true; } return false; @@ -762,6 +762,7 @@ find_implicit_erroneous_behavior (void) /* We've got a NULL PHI argument. Now see if the PHI's result is dereferenced within BB. */ + auto_vec uses_in_bb; FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs) { /* We only care about uses in BB. Catching cases in @@ -774,18 +775,23 @@ find_implicit_erroneous_behavior (void) ? gimple_location (use_stmt) : phi_arg_loc; - if (stmt_uses_name_in_undefined_way (use_stmt, lhs, loc) - && (duplicate || can_duplicate_block_p (bb))) + if (stmt_uses_name_in_undefined_way (use_stmt, lhs, loc)) { - duplicate = isolate_path (bb, duplicate, e, - use_stmt, lhs, false); - - /* When we remove an incoming edge, we need to - reprocess the Ith element. */ - next_i = i; - cfg_altered = true; + if (!can_duplicate_block_p (bb)) + break; + uses_in_bb.safe_push (use_stmt); } } + for (gimple *use_stmt : uses_in_bb) + { + duplicate = isolate_path (bb, duplicate, e, + use_stmt, lhs, false); + + /* When we remove an incoming edge, we need to + reprocess the Ith element. */ + next_i = i; + cfg_altered = true; + } } } }