----- testcase.f ----- common/main1/ eps(2) call dalie6s(iqmod6,1,wx,cor6d) end ---------------------- reduced from gfortran.dg/lto/20091015-1_2.f Compiler output: $ gfortran -O -finline-small-functions -flto -g testcase.f -r -nostdlib ==5279== Invalid read of size 2 ==5279== at 0x5C75BC: add_name_and_src_coords_attributes (dwarf2out.c:17792) ==5279== by 0x5D8104: gen_variable_die (dwarf2out.c:19400) ==5279== by 0x5DCF14: gen_decl_die (dwarf2out.c:20981) ==5279== by 0x5DA34A: decls_for_scope (dwarf2out.c:20555) ==5279== by 0x5DF38B: gen_block_die (dwarf2out.c:19669) ==5279== by 0x5DA37D: decls_for_scope (dwarf2out.c:20567) ==5279== by 0x5DF582: gen_block_die (dwarf2out.c:19701) ==5279== by 0x5DA37D: decls_for_scope (dwarf2out.c:20567) ==5279== by 0x5DA8FF: gen_subprogram_die (dwarf2out.c:19277) ==5279== by 0x5DCDA2: gen_decl_die (dwarf2out.c:20914) ==5279== by 0x5E00E8: dwarf2out_function_decl (dwarf2out.c:21296) ==5279== by 0x638FCC: rest_of_handle_final (final.c:4286) ==5279== by 0x771ADE: execute_one_pass (passes.c:1553) ==5279== by 0x771DA4: execute_pass_list (passes.c:1608) ==5279== by 0x771DB6: execute_pass_list (passes.c:1609) ==5279== by 0x771DB6: execute_pass_list (passes.c:1609) ==5279== by 0x8B2605: tree_rest_of_compilation (tree-optimize.c:422) ==5279== by 0xA77EB1: cgraph_expand_function (cgraphunit.c:1508) ==5279== by 0xA7A489: cgraph_optimize (cgraphunit.c:1567) ==5279== by 0x4FF78E: lto_main (lto.c:2453) ==5279== by 0x85BDE7: toplev_main (toplev.c:579) ==5279== by 0x6369BBC: (below main) (in /lib64/libc-2.11.2.so) ==5279== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==5279== In file included from :0:0: testcase.f: In function 'main': testcase.f:3:0: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. lto-wrapper: /mnt/svn/gcc-trunk/binary-167643-lto-fortran-checking-yes-rtl-df/bin/gfortran returned 1 exit status collect2: lto-wrapper returned 1 exit status Tested revisions: r167643 - crash r165699 - crash r161659 - OK 4.5 r166509 - OK
When dwarf2out_abstract_function is called on MAIN__, it doesn't have DECL_INITIAL set when in lto1 (compared to f951), the BLOCK tree is simply not present, which both causes incomplete debug information and for Fortran COMMON blocks ICEs, as it relies on those to be actually present. P4 as it only affects Fortran, but if -flto -g is ever meant to be usable, the BLOCK trees need to be streamed out and preserved. It seems output_function calls: /* Output DECL_INITIAL for the function, which contains the tree of lexical scopes. */ lto_output_tree (ob, DECL_INITIAL (function), true); but for inlines output_function isn't called.
(In reply to comment #1) > When dwarf2out_abstract_function is called on MAIN__, it doesn't have > DECL_INITIAL set when in lto1 (compared to f951), the BLOCK tree is simply not > present, which both causes incomplete debug information and for Fortran COMMON > blocks ICEs, as it relies on those to be actually present. P4 as it only > affects Fortran, but if -flto -g is ever meant to be usable, the BLOCK trees > need to be streamed out and preserved. It seems output_function calls: > /* Output DECL_INITIAL for the function, which contains the tree of > lexical scopes. */ > lto_output_tree (ob, DECL_INITIAL (function), true); > but for inlines output_function isn't called. That's true. Inlines would be reachable via the block trees abstract origins, right? We do stream that, so the only thing missing is associating it with the function-decl ... (maybe we can do that when reading the BLOCK and its context is a FUNCTION_DECL?)
Yeah, all the inlines should be BLOCK_ABSTRACT_ORIGIN of some BLOCK that is being streamed, so in theory all of them should be already streamed, just DECL_INITIAL is not filled in.
We already do /* We re-compute BLOCK_SUBBLOCKS of our parent here instead of streaming it. For non-BLOCK BLOCK_SUPERCONTEXTs we still stream the child relationship explicitly. */ if (BLOCK_SUPERCONTEXT (expr) && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == BLOCK) { BLOCK_CHAIN (expr) = BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr)); BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr)) = expr; } so adding a if (BLOCK_SUPERCONTEXT (expr) && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == FUNCTION_DECL) DECL_INITIAL (BLOCK_SUPERCONTEXT (expr)) = expr; shouldn't be too bad - but it does not fixe the testcase ... (but DECL_INITIAL is now filled in correctly - I bet without VAR_DECLs though).
Same happens for 416.gamess.
There are several issues. First as Jakub noted we have a NULL DECL_INITAL for the inlined __MAIN. If we fix that during LTO streaming (avoiding direct input/output of DECL_INITIAL of all FUNCTION_DECLs) we run into the issue that cgraph sets DECL_INITIAL of __MAIN to error_mark_node after inlining it (assuming that debug_hooks->outlining_inline_function did everything that was necessary already). We can try to avoid this by setting abstract_and_needed in the cgraph node. Together this solves this ICE. It doesn't solve PR47799 though. This is because how we split trees between the global and the function-local sections during streaming. We end up with multiple copies of the abstract BLOCK tree as well as bogus cross-function references for all abstract origins (apart from that to the function-decl itself).
Created attachment 23443 [details] prototype patch Patch also trying to fix PR47799 (but we'll still have multiple copies of the BLOCK trees). For better clarity the BLOCK_ABSTRACT_ORIGIN BLOCK trees should probably be streamed from input/output_function by walking the functions DECL_INITIAL. That would make it clear that the BLOCKs are duplicated in each caller function section (and that we mess up DECL_INITIAL of the abstract origin function-decls for all but the last function). We probably need to output the abstract function and its BLOCK tree to the global decl&type LTO section, possibly triggered by debug_hooks->outlining_inline_function.
Author: rguenth Date: Tue Mar 1 09:45:05 2011 New Revision: 170588 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170588 Log: 2011-03-01 Richard Guenther <rguenther@suse.de> PR lto/46911 * lto-streamer-in.c (lto_input_ts_decl_common_tree_pointers): Do not stream DECL_ABSTRACT_ORIGIN. (lto_input_ts_block_tree_pointers): Nor BLOCK_SOURCE_LOCATION, BLOCK_NONLOCALIZED_VARS or BLOCK_ABSTRACT_ORIGIN. * lto-streamer-out.c (lto_output_ts_decl_common_tree_pointers): Do not stream DECL_ABSTRACT_ORIGIN. (lto_output_ts_block_tree_pointers): Nor BLOCK_SOURCE_LOCATION, BLOCK_NONLOCALIZED_VARS or BLOCK_ABSTRACT_ORIGIN. * gfortran.dg/lto/pr46911_0.f: New testcase. Added: trunk/gcc/testsuite/gfortran.dg/lto/pr46911_0.f Modified: trunk/gcc/ChangeLog trunk/gcc/lto-streamer-in.c trunk/gcc/lto-streamer-out.c trunk/gcc/testsuite/ChangeLog
Fixed.