On Sun, 13 Oct 2024, Richard Biener wrote: > 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. > > Bootstrapped and tested on x86_64-unknown-linux-gnu, OK?
I've applied this now, cleaning is required unless the DECL_VALUE_EXPR itself shouldn't be there in which case it is harmless in general. We do stream DECL_VALUE_EXPR to LTO so some are definitely expected. Richard. > Thanks, > Richard. > > PR tree-optimization/116907 > * tree-ssa-live.cc (clear_unused_block_pointer_in_block): New > helper. > (clear_unused_block_pointer): Call it. > --- > gcc/tree-ssa-live.cc | 20 ++++++++++++++++++++ > 1 file changed, 20 insertions(+) > > diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc > index 0739faa022e..484698899cf 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 > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)