https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118790
--- Comment #30 from rguenther at suse dot de <rguenther at suse dot de> --- On Wed, 12 Feb 2025, jakub at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118790 > > --- Comment #28 from Jakub Jelinek <jakub at gcc dot gnu.org> --- > --- gcc/tree-ssa-live.cc.jj 2025-02-12 11:03:53.607556187 +0100 > +++ gcc/tree-ssa-live.cc 2025-02-12 11:54:34.779131237 +0100 > @@ -369,9 +369,17 @@ mark_all_vars_used_1 (tree *tp, int *wal > { > /* When a global var becomes used for the first time also walk its > initializer (non global ones don't have any). */ > - if (set_is_used (t) && is_global_var (t) > - && DECL_CONTEXT (t) == current_function_decl) > - mark_all_vars_used (&DECL_INITIAL (t)); > + if (set_is_used (t)) > + { > + if (is_global_var (t) > + && DECL_CONTEXT (t) == current_function_decl) > + mark_all_vars_used (&DECL_INITIAL (t)); > + if (DECL_HAS_VALUE_EXPR_P (t)) > + { > + tree dve = DECL_VALUE_EXPR (t); > + mark_all_vars_used (&dve); > + } > + } > } > /* remove_unused_scope_block_p requires information about labels > which are not DECL_IGNORED_P to tell if they might be used in the IL. > */ > @@ -389,7 +397,9 @@ mark_all_vars_used_1 (tree *tp, int *wal > } > > /* Mark the scope block SCOPE and its subblocks unused when they can be > - possibly eliminated if dead. */ > + possibly eliminated if dead. Also, as remove_unused_scope_block_p is > going > + to keep all BLOCK_VARS VAR_DECLs with DECL_HAS_VALUE_EXPR_P, mark all vars > + their DECL_VALUE_EXPR refers to. */ > > static void > mark_scope_block_unused (tree scope) > @@ -398,6 +408,12 @@ mark_scope_block_unused (tree scope) > TREE_USED (scope) = false; > if (!(*debug_hooks->ignore_block) (scope)) > TREE_USED (scope) = true; > + for (t = BLOCK_VARS (scope); t; t = DECL_CHAIN (t)) > + if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t)) > + { > + tree dve = DECL_VALUE_EXPR (t); > + mark_all_vars_used (&dve); > + } > for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t)) > mark_scope_block_unused (t); > } > @@ -792,9 +808,10 @@ remove_unused_locals (void) > > timevar_push (TV_REMOVE_UNUSED); > > + usedvars = BITMAP_ALLOC (NULL); > + > mark_scope_block_unused (DECL_INITIAL (current_function_decl)); > > - usedvars = BITMAP_ALLOC (NULL); > auto_bitmap useddebug; > > /* Walk the CFG marking all referenced symbols. */ > @@ -819,7 +836,7 @@ remove_unused_locals (void) > { > if (gimple_debug_bind_p (stmt)) > { > - tree var = gimple_debug_bind_get_var (stmt); > + tree var = gimple_debug_bind_get_var (stmt); > if (VAR_P (var)) > { > if (!gimple_debug_bind_get_value (stmt)) > preserves it in local_decls where it was earlier removed. > This keeps DECL_VALUE_EXPR (id_string.55) working until the expand pass. > That throws the VAR_DECL from local_decls again in expand_used_vars, e.g. > expand_one_var doesn't do anything for DECL_HAS_VALUE_EXPR_P VAR_DECLs. > And then instantiate_decls even vec_frees the whole cfun->local_decls (though > by that time DECL_VALUE_EXPR (id_string.55) has been garbage collected > already. > So perhaps instead we want to move such vars from local_decls to BLOCK_VARS of > the outermost block or something? But how to find out if it wasn't there > already? I don't think moving is feasible, but ... > Note, normally these VLA addresses don't have DECL_VALUE_EXPR and so are > usually used in the IL. It is just that tree-nested.cc in this case added > DECL_VALUE_EXPR on those because they are (or were) referenced from nested > function. I think the intent for this is to reflect this into debug info. So, ... I think tree-nested.cc should put amend the related VAR which should be already somewhere in BLOCK_VARS?