https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116907
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #31 from Richard Biener <rguenth at gcc dot gnu.org> --- The issue still reproduces for me with the original preprocessed source but not with either of the reduced testcases. As Honza says, we're probably missing a location stripping. I wonder if we can "sanitize" IPA info streaming by switching to a mode where all BLOCKs are diagnosed ...? Note the backtrace points at that we're streaming the BLOCK tree: during IPA pass: modref src/option_types.cc:24:1: internal compiler error: tree check: expected tree that contains ‘typed’ structure, have ‘ggc_freed’ in DFS_write_tree_body, at lto-streamer-out.cc:968 0x3ab3231 internal_error(char const*, ...) ../../src/gcc/gcc/diagnostic-global-context.cc:517 0x2054423 tree_contains_struct_check_failed(tree_node const*, tree_node_structure_enum, char const*, int, char const*) ../../src/gcc/gcc/tree.cc:9177 0xe618d7 contains_struct_check(tree_node*, tree_node_structure_enum, char const*, int, char const*) ../../src/gcc/gcc/tree.h:3779 0x199298f DFS::DFS_write_tree_body(output_block*, tree_node*, DFS::sccs*, bool) ../../src/gcc/gcc/lto-streamer-out.cc:968 0x1991f5e DFS::DFS(output_block*, tree_node*, bool, bool, bool) ../../src/gcc/gcc/lto-streamer-out.cc:734 0x199a23b lto_output_tree(output_block*, tree_node*, bool, bool) ../../src/gcc/gcc/lto-streamer-out.cc:1862 0x199c0f2 output_function ../../src/gcc/gcc/lto-streamer-out.cc:2453 ^^ this is /* As we do not recurse into BLOCK_SUBBLOCKS but only BLOCK_SUPERCONTEXT collect block tree leafs and stream those. */ auto_vec<tree> block_tree_leafs; if (DECL_INITIAL (function) && DECL_INITIAL (function) != error_mark_node) collect_block_tree_leafs (DECL_INITIAL (function), block_tree_leafs); streamer_write_uhwi (ob, block_tree_leafs.length ()); for (unsigned i = 0; i < block_tree_leafs.length (); ++i) stream_write_tree (ob, block_tree_leafs[i], true); we are coming from following TREE_BLOCK of &factory.func but unfortunately ob->section_type is LTO_section_function_body rather than distinguishable LTO_IPA_tree_data or so. The address is in BLOCK_VARS via <block 0x7ffff5760c00 used supercontext <block 0x7ffff5760ba0 used vars <var_decl 0x7fffe0c0be10 t type <record_type 0x7fffe28082a0 ._anon_161> readonly used read decl_1 QI src/ranges.hh:276:24 size <integer_cst 0x7ffff6821348 constant 8> unit-size <integer_cst 0x7ffff6821360 constant 1> align:8 warn_if_not_align:0 context <function_decl 0x7fffe2bc9b00 option_to_strings> abstract_origin <var_decl 0x7fffe2815360 t> value-expr <component_ref 0x7ffff2b4c510 type <record_type 0x7fffe28082a0 ._anon_161> readonly arg:0 <indirect_ref 0x7fffe2723760 type <record_type 0x7fffe280adc8 ._anon_162> readonly arg:0 <nop_expr 0x7fffe23633c0 type <pointer_type 0x7fffe280af18> readonly arg:0 <addr_expr 0x7fffe23633e0 type <pointer_type 0x7fffe2812150> arg:0 <component_ref 0x7ffff2b4c5d0> src/ranges.hh:23:24 start: src/ranges.hh:23:12 finish: src/ranges.hh:23:51>>> arg:1 <field_decl 0x7fffe280b1c8 __t>>> which is a DECL_VALUE_EXPR of ((const struct ._anon_162 *) &factory.func)->__t I think that ipa_modref is reported as active pass is just bogus. I'm not sure in what cases we keep DECL_VALUE_EXPR and why but it seems that we do not specifically consider expressions in DECL_VALUE_EXPRs when computing BLOCKs we need to keep in tree-ssa-live.cc - we only keep BLOCKs that have vars with DECL_VALUE_EXPR. Maybe we should drop all BLOCK references from DECL_VALUE_EXPRs, but we are also not considering mentioned variables to be used AFAICS. I'll note the variable with the DECL_VALUE_EXPR is in the BLOCK tree but not in local_decls. Clearing BLOCKs in those like we do elsewhere via clear_unused_block_pointer works. Testing patch.