aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-10-13 12:44:04 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2024-10-15 13:32:18 +0200
commit7d15248d41dc45a4ba2d38ff532b672a5c0651d0 (patch)
tree1846b6a7625ca616973471b0a6e230831974b4a0
parent97f98855d4157a2511a713129ec77740fe6f88dc (diff)
downloadgcc-7d15248d41dc45a4ba2d38ff532b672a5c0651d0.zip
gcc-7d15248d41dc45a4ba2d38ff532b672a5c0651d0.tar.gz
gcc-7d15248d41dc45a4ba2d38ff532b672a5c0651d0.tar.bz2
tree-optimization/116907 - stale BLOCK reference from DECL_VALUE_EXPR
When we remove unused BLOCKs we fail to clean references to them from DECL_VALUE_EXPRs of variables in other BLOCKs which in the PR causes LTO streaming to walk into pointers to GGC freed blocks. There's the question of whether such DECL_VALUE_EXPRs should keep variables and blocks referenced live (it doesn't seem to do that) and whether such DECL_VALUE_EXPRs should have survived in the first place. PR tree-optimization/116907 * tree-ssa-live.cc (clear_unused_block_pointer_in_block): New helper. (clear_unused_block_pointer): Call it.
-rw-r--r--gcc/tree-ssa-live.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc
index 0739faa..4846988 100644
--- a/gcc/tree-ssa-live.cc
+++ b/gcc/tree-ssa-live.cc
@@ -612,6 +612,22 @@ clear_unused_block_pointer_1 (tree *tp, int *, void *)
return NULL_TREE;
}
+/* Clear references to unused BLOCKs from DECL_VALUE_EXPRs of variables
+ in BLOCK. */
+
+static void
+clear_unused_block_pointer_in_block (tree block)
+{
+ for (tree t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
+ if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
+ {
+ tree val = DECL_VALUE_EXPR (t);
+ walk_tree (&val, clear_unused_block_pointer_1, NULL, NULL);
+ }
+ for (tree t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
+ clear_unused_block_pointer_in_block (t);
+}
+
/* Set all block pointer in debug or clobber stmt to NULL if the block
is unused, so that they will not be streamed out. */
@@ -667,6 +683,10 @@ clear_unused_block_pointer (void)
walk_tree (gimple_op_ptr (stmt, i), clear_unused_block_pointer_1,
NULL, NULL);
}
+
+ /* Walk all variables mentioned in the functions BLOCK tree and clear
+ DECL_VALUE_EXPR from unused blocks where present. */
+ clear_unused_block_pointer_in_block (DECL_INITIAL (current_function_decl));
}
/* Dump scope blocks starting at SCOPE to FILE. INDENT is the