Bug 46911 - [4.6 Regression] ICE: SIGSEGV in add_name_and_src_coords_attributes (dwarf2out.c:17792) with -flto -g
Summary: [4.6 Regression] ICE: SIGSEGV in add_name_and_src_coords_attributes (dwarf2ou...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.6.0
: P4 normal
Target Milestone: 4.6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, lto
Depends on:
Blocks: 47819
  Show dependency treegraph
 
Reported: 2010-12-12 17:15 UTC by Zdenek Sojka
Modified: 2011-03-01 09:46 UTC (History)
1 user (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work: 4.5.2
Known to fail: 4.6.0
Last reconfirmed: 2011-01-18 17:38:15


Attachments
prototype patch (1.51 KB, patch)
2011-02-23 14:35 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2010-12-12 17:15:57 UTC
----- 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
Comment 1 Jakub Jelinek 2011-01-18 17:38:15 UTC
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.
Comment 2 Richard Biener 2011-01-19 16:53:11 UTC
(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?)
Comment 3 Jakub Jelinek 2011-01-19 16:55:55 UTC
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.
Comment 4 Richard Biener 2011-01-19 17:10:31 UTC
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).
Comment 5 Richard Biener 2011-02-23 12:06:34 UTC
Same happens for 416.gamess.
Comment 6 Richard Biener 2011-02-23 13:34:25 UTC
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).
Comment 7 Richard Biener 2011-02-23 14:35:27 UTC
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.
Comment 8 Richard Biener 2011-03-01 09:45:09 UTC
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
Comment 9 Richard Biener 2011-03-01 09:46:36 UTC
Fixed.