Bug 88902

Summary: ICE: Segmentation fault (in DFS::DFS_write_tree_body)
Product: gcc Reporter: Arseny Solokha <asolokha>
Component: fortranAssignee: Jakub Jelinek <jakub>
Status: RESOLVED FIXED    
Severity: normal CC: jakub, kargls, pault
Priority: P3 Keywords: GC, ice-on-valid-code
Version: 9.0   
Target Milestone: 9.0   
Host: x86_64-pc-linux-gnu Target:
Build: Known to work:
Known to fail: 8.2.0, 9.0 Last reconfirmed: 2019-01-18 00:00:00
Attachments: gcc9-pr88902.patch

Description Arseny Solokha 2019-01-18 09:50:06 UTC
gfortran-9.0.0-alpha20190113 snapshot (r267906) ICEs when compiling gcc/testsuite/gfortran.dg/pr50069_2.f90 w/ -flto --param ggc-min-heapsize=0:

% powerpc-e300c3-linux-gnu-gfortran-9.0.0-alpha20190113 -flto --param ggc-min-heapsize=0 -c gcc/testsuite/gfortran.dg/pr50069_2.f90
during IPA pass: fnsummary
gcc/testsuite/gfortran.dg/pr50069_2.f90:11: internal compiler error: Segmentation fault
   11 | end function reverse
      | 
0xd9fad6 crash_signal
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/toplev.c:326
0xc46ef8 DFS::DFS_write_tree_body(output_block*, tree_node*, DFS::sccs*, bool)
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/lto-streamer-out.c:759
0xc4f69d DFS::DFS(output_block*, tree_node*, bool, bool, bool)
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/lto-streamer-out.c:587
0xc50620 lto_output_tree(output_block*, tree_node*, bool, bool)
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/lto-streamer-out.c:1628
0xc47ebc write_global_stream
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/lto-streamer-out.c:2511
0xc47ebc lto_output_decl_state_streams(output_block*, lto_out_decl_state*)
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/lto-streamer-out.c:2558
0xc4e504 produce_asm_for_decls()
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/lto-streamer-out.c:2898
0xcc1927 write_lto
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/passes.c:2596
0xcc5290 ipa_write_summaries_1
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/passes.c:2657
0xcc5290 ipa_write_summaries()
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/passes.c:2720
0x9813fc ipa_passes
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/cgraphunit.c:2530
0x9813fc symbol_table::compile()
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/cgraphunit.c:2618
0x983db8 symbol_table::finalize_compilation_unit()
	/var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-9.0.0_alpha20190113/work/gcc-9-20190113/gcc/cgraphunit.c:2863

(While my target here is powerpc, the ICE not target-specific.)
Comment 1 Martin Liška 2019-01-18 09:59:03 UTC
Confirmed on x86_64, let me bisect that.
Comment 2 Martin Liška 2019-01-18 11:21:13 UTC
So it's there since the fix of PR50069 (r244601). Thus I guess it's a Fortran error.
Comment 3 Martin Liška 2019-01-18 11:26:59 UTC
So the FE creates an identifier node:

$ (gdb) p debug_tree((tree_node *) 0x7ffff6d340c8)
 <identifier_node 0x7ffff6d340c8 (null)>

which is then removed by GGC:

Old value = IDENTIFIER_NODE
New value = 2779096485
__memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:166
166		VZEROUPPER
(gdb) bt
#0  __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:166
#1  0x000000000098f8f5 in poison_pages () at ../../gcc/ggc-page.c:2113
#2  0x000000000098fa79 in ggc_collect () at ../../gcc/ggc-page.c:2208
#3  0x0000000000e66c14 in execute_one_pass (pass=<opt_pass* 0x2826790 "omplower"(12)>) at ../../gcc/passes.c:2479
#4  0x0000000000e66c6a in execute_pass_list_1 (pass=<opt_pass* 0x2826790 "omplower"(12)>) at ../../gcc/passes.c:2494
#5  0x0000000000e66cf3 in execute_pass_list (fn=0x7ffff6d35000, pass=<opt_pass* 0x2803b80 "*warn_unused_result"(-1)>) at ../../gcc/passes.c:2505
#6  0x0000000000a42c3b in cgraph_node::analyze (this=<cgraph_node* 0x7ffff6d3b000 "reverse">) at ../../gcc/cgraphunit.c:637
#7  0x0000000000a4448d in analyze_functions (first_time=true) at ../../gcc/cgraphunit.c:1087
#8  0x0000000000a48d6c in symbol_table::finalize_compilation_unit (this=0x7ffff6b56100) at ../../gcc/cgraphunit.c:2562
#9  0x0000000000f8b7ee in compile_file () at ../../gcc/toplev.c:488
#10 0x0000000000f8dcf1 in do_compile () at ../../gcc/toplev.c:1983
#11 0x0000000000f8dfce in toplev::main (this=0x7fffffffd9de, argc=16, argv=0x7fffffffdad8) at ../../gcc/toplev.c:2117
#12 0x0000000001b75230 in main (argc=16, argv=0x7fffffffdad8) at ../../gcc/main.c:39

So the tree is somehow lost.
Comment 4 Jakub Jelinek 2019-01-18 11:54:43 UTC
The problem is that gfc_add_decl_to_parent_function is called multiple times on <var_decl 0x7ffff7ffbab0 ..__result> and thus for that VAR_DECL DECL_CHAIN (decl) == decl (or in theory there could be longer loop, but any loop in DECL_CHAIN is invalid).
Comment 5 Jakub Jelinek 2019-01-18 11:55:45 UTC
--- gcc/fortran/trans-decl.c.jj	2019-01-16 09:35:08.000000000 +0100
+++ gcc/fortran/trans-decl.c	2019-01-18 12:52:45.205618524 +0100
@@ -1572,13 +1572,17 @@ gfc_get_symbol_decl (gfc_symbol * sym)
 	  if (VAR_P (length) && DECL_FILE_SCOPE_P (length))
 	    {
 	      /* Add the string length to the same context as the symbol.  */
-	      if (DECL_CONTEXT (sym->backend_decl) == current_function_decl)
-	        gfc_add_decl_to_function (length);
-	      else
-		gfc_add_decl_to_parent_function (length);
+	      if (DECL_CONTEXT (length) == NULL_TREE)
+		{
+		  if (DECL_CONTEXT (sym->backend_decl)
+		      == current_function_decl)
+		    gfc_add_decl_to_function (length);
+		  else
+		    gfc_add_decl_to_parent_function (length);
+		}
 
-	      gcc_assert (DECL_CONTEXT (sym->backend_decl) ==
-			    DECL_CONTEXT (length));
+	      gcc_assert (DECL_CONTEXT (sym->backend_decl)
+			  == DECL_CONTEXT (length));
 
 	      gfc_defer_symbol_init (sym);
 	    }

fixes this.
Comment 6 Jakub Jelinek 2019-01-18 12:05:22 UTC
Created attachment 45460 [details]
gcc9-pr88902.patch

Full untested patch.
Comment 7 Jakub Jelinek 2019-01-19 08:43:44 UTC
Author: jakub
Date: Sat Jan 19 08:43:12 2019
New Revision: 268091

URL: https://gcc.gnu.org/viewcvs?rev=268091&root=gcc&view=rev
Log:
	PR fortran/88902
	* trans-decl.c (gfc_get_symbol_decl): Don't add length to function
	or parent function if it has been added there already.

	* gfortran.dg/pr88902.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/pr88902.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2019-01-19 08:44:53 UTC
Fixed on the trunk so far.
Comment 9 Jakub Jelinek 2019-02-07 14:33:39 UTC
Author: jakub
Date: Thu Feb  7 14:33:07 2019
New Revision: 268623

URL: https://gcc.gnu.org/viewcvs?rev=268623&root=gcc&view=rev
Log:
	Backported from mainline
	2019-01-19  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/88902
	* trans-decl.c (gfc_get_symbol_decl): Don't add length to function
	or parent function if it has been added there already.

	* gfortran.dg/pr88902.f90: New test.

Added:
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/pr88902.f90
Modified:
    branches/gcc-8-branch/gcc/fortran/ChangeLog
    branches/gcc-8-branch/gcc/fortran/trans-decl.c
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
Comment 10 Jakub Jelinek 2019-02-07 15:08:22 UTC
Fixed for 8.3+ too.
Comment 11 Jakub Jelinek 2019-08-30 11:28:53 UTC
Author: jakub
Date: Fri Aug 30 11:28:22 2019
New Revision: 275088

URL: https://gcc.gnu.org/viewcvs?rev=275088&root=gcc&view=rev
Log:
	Backported from mainline
	2019-01-19  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/88902
	* trans-decl.c (gfc_get_symbol_decl): Don't add length to function
	or parent function if it has been added there already.

	* gfortran.dg/pr88902.f90: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/pr88902.f90
Modified:
    branches/gcc-7-branch/gcc/fortran/ChangeLog
    branches/gcc-7-branch/gcc/fortran/trans-decl.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog