https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118790
--- Comment #26 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, seems id_string is mentioned in BLOCK_VARS of the ec_meminfo BLOCK: BLOCK #0 [written] SUPERCONTEXT: ec_meminfo SUBBLOCKS: BLOCK #109 [written] BLOCK #166 [written] BLOCK #167 [written] BLOCK #168 [written] BLOCK #169 [written] VARS: rnsort check_error prt_data slash_proc i nproc error clpfx .id_string id_string line node k n18 smallpage nnuma j bucket hugepage memfree cached clstr coreids icoreid iorank ubound.30 irecv_status itag lastnode llfirst_time llnocomm maxth mpi_byte mpi_comm_world mpi_integer4 myproc myth rn i even before any unused var removals. While id_string.55 is created in the gimplifier, gimplify_vla_decl on id_string: 1981 addr = create_tmp_var (ptr_type, get_name (decl)); 1982 DECL_IGNORED_P (addr) = 0; 1983 t = build_fold_indirect_ref (addr); 1984 TREE_THIS_NOTRAP (t) = 1; 1985 SET_DECL_VALUE_EXPR (decl, t); and so it is added to cfun->local_decls. Now, during remove_unused_locals, neither id_string nor id_string.55 are actually marked as used, they are not used in the IL anymore. But id_string is preserved in BLOCK_VARS due to remove_unused_scope_block_p: /* If a decl has a value expr, we need to instantiate it regardless of debug info generation, to avoid codegen differences in memory overlap tests. update_equiv_regs() may indirectly call validate_equiv_mem() to test whether a SET_DEST overlaps with others, and if the value expr changes by virtual register instantiation, we may get end up with different results. */ else if (VAR_P (*t) && DECL_HAS_VALUE_EXPR_P (*t)) unused = false; (added in r0-93860). But nothing does that something similar for VAR_DECLs with DECL_HAS_VALUE_EXPR_P in local_decls. So, shall we always preserve all the DECL_HAS_VALUE_EXPR_P local_decls? Or shall we mark the DECL_HAS_VALUE_EXPR_P VAR_DECLs and their DECL_VALUE_EXPRs as used? Something else?