Patchwork Fix dwarf2out_finish ICE (PR debug/45660)

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 13, 2010, 9:09 p.m.
Message ID <20100913210953.GF1269@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/64658/
State New
Headers show

Comments

Jakub Jelinek - Sept. 13, 2010, 9:09 p.m.
Hi!

On the attached testcase cc1plus ICEs in dwarf2out_finish, because
when creating DIE for i we first create DIE for T typedef (thus it is
created as limbo DIE node), and only afterwards create the containing class'
DIE.  When processing its T member, TREE_ASM_WRITTEN is already set, thus
nothing sets the T DIE's die_parent and in dwarf2out_finish we ICE because
die_parent is still NULL, but its context isn't fndecl or namespace, but
a class.

Fixed by making sure to create DIE for the class before creating DIE for
the return type.  Bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk/4.5?

2010-09-13  Jakub Jelinek  <jakub@redhat.com>

	PR debug/45660
	* dwarf2out.c (gen_decl_die): Call gen_type_die for origin before
	gen_type_die for function/method return type.

	* g++.dg/debug/pr45660.C: New test.


	Jakub
Jason Merrill - Sept. 14, 2010, 4:01 a.m.
OK.

Jason

Patch

--- gcc/dwarf2out.c.jj	2010-09-09 10:17:41.000000000 +0200
+++ gcc/dwarf2out.c	2010-09-13 20:18:24.000000000 +0200
@@ -20596,16 +20596,20 @@  gen_decl_die (tree decl, tree origin, dw
       else if (debug_info_level > DINFO_LEVEL_TERSE)
 	{
 	  /* Before we describe the FUNCTION_DECL itself, make sure that we
-	     have described its return type.  */
+	     have its containing type.  */
+	  if (!origin)
+	    origin = decl_class_context (decl);
+	  if (origin != NULL_TREE)
+	    gen_type_die (origin, context_die);
+
+	  /* And its return type.  */
 	  gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
 
 	  /* And its virtual context.  */
 	  if (DECL_VINDEX (decl) != NULL_TREE)
 	    gen_type_die (DECL_CONTEXT (decl), context_die);
 
-	  /* And its containing type.  */
-	  if (!origin)
-	    origin = decl_class_context (decl);
+	  /* Make sure we have a member DIE for decl.  */
 	  if (origin != NULL_TREE)
 	    gen_type_die_for_member (origin, decl, context_die);
 
--- gcc/testsuite/g++.dg/debug/pr45660.C.jj	2010-09-13 19:57:39.000000000 +0200
+++ gcc/testsuite/g++.dg/debug/pr45660.C	2010-09-13 19:52:49.000000000 +0200
@@ -0,0 +1,16 @@ 
+// PR debug/45660
+// { dg-do compile }
+// { dg-options "-g -fno-inline" }
+
+void
+test ()
+{
+  struct S
+  {
+    typedef void (**T) (void);
+    static T i (void) { return 0; }
+  };
+  S s;
+  if (s.i ())
+    *s.i () = 0;
+}