Patchwork Fix ICE with -feliminate-dwarf2-dups or -gdwarf-4 (PR debug/46123)

login
register
mail settings
Submitter Jason Merrill
Date Nov. 30, 2010, 11:07 p.m.
Message ID <4CF5839F.1080608@redhat.com>
Download mbox | patch
Permalink /patch/73678/
State New
Headers show

Comments

Jason Merrill - Nov. 30, 2010, 11:07 p.m.
On 11/27/2010 12:51 AM, Jason Merrill wrote:
> Right, so the concrete instance needs to move to be under comp_unit_die.

The problem with this is that separating the abstract and concrete 
instances between CUs means we need more symbolic refs, since not only 
the function itself has AT_abstract_origin.  So that's not the right fix.

I poked around at this for a while myself; I was puzzled as to why we 
were trying to put the local type in a comdat unit in the first place, 
since it's internal to a function.  It turned out that we were wrongly 
attaching the local type to the declaration die for the containing 
function; fixing that makes your testcases pass.  Does this patch make 
sense to you?
commit 61e1c85d04c7f2e57b5e4da45c904479f82c240e
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Nov 29 20:30:04 2010 -0500

    	PR debug/46123
    	* dwarf2out.c (gen_tagged_type_die): Don't put local types in
    	a declaration DIE.
Jakub Jelinek - Dec. 1, 2010, 7:35 a.m.
On Tue, Nov 30, 2010 at 06:07:11PM -0500, Jason Merrill wrote:
> On 11/27/2010 12:51 AM, Jason Merrill wrote:
> I poked around at this for a while myself; I was puzzled as to why
> we were trying to put the local type in a comdat unit in the first
> place, since it's internal to a function.  It turned out that we
> were wrongly attaching the local type to the declaration die for the
> containing function; fixing that makes your testcases pass.  Does
> this patch make sense to you?
> 

> commit 61e1c85d04c7f2e57b5e4da45c904479f82c240e
> Author: Jason Merrill <jason@redhat.com>
> Date:   Mon Nov 29 20:30:04 2010 -0500
> 
>     	PR debug/46123
>     	* dwarf2out.c (gen_tagged_type_die): Don't put local types in
>     	a declaration DIE.
> 

Yeah, this makes sense.  Thanks for looking into it.

	Jakub

Patch

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index e230861..b6a26c8 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20186,6 +20186,10 @@  gen_tagged_type_die (tree type,
 	 out yet, use a NULL context for now; it will be fixed up in
 	 decls_for_scope.  */
       context_die = lookup_decl_die (TYPE_CONTEXT (type));
+      /* A declaration DIE doesn't count; nested types need to go in the
+	 specification.  */
+      if (is_declaration_die (context_die))
+	context_die = NULL;
       need_pop = 0;
     }
   else
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr46123.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr46123.C
new file mode 100644
index 0000000..eee192c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr46123.C
@@ -0,0 +1,47 @@ 
+// PR debug/46123
+// { dg-do compile }
+// { dg-options "-gdwarf-4" }
+
+struct foo
+{
+  static int bar ()
+  {
+    int i;
+    static int baz = 1;
+    {
+      static int baz = 2;
+      i = baz++;
+    }
+    {
+      struct baz
+      {
+	static int m ()
+	{
+	  static int n;
+	  return n += 10;
+	}
+      };
+      baz a;
+      i += a.m ();
+    }
+    {
+      static int baz = 3;
+      i += baz;
+      baz += 30;
+    }
+    i += baz;
+    baz += 60;
+    return i;
+  }
+};
+
+int main ()
+{
+  foo x;
+
+  if (x.bar () != 16)
+    return 1;
+  if (x.bar() != 117)
+    return 1;
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/debug/pr46123.C b/gcc/testsuite/g++.dg/debug/pr46123.C
new file mode 100644
index 0000000..9e115cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/pr46123.C
@@ -0,0 +1,47 @@ 
+// PR debug/46123
+// { dg-do compile }
+// { dg-options "-g -feliminate-dwarf2-dups" }
+
+struct foo
+{
+  static int bar ()
+  {
+    int i;
+    static int baz = 1;
+    {
+      static int baz = 2;
+      i = baz++;
+    }
+    {
+      struct baz
+      {
+	static int m ()
+	{
+	  static int n;
+	  return n += 10;
+	}
+      };
+      baz a;
+      i += a.m ();
+    }
+    {
+      static int baz = 3;
+      i += baz;
+      baz += 30;
+    }
+    i += baz;
+    baz += 60;
+    return i;
+  }
+};
+
+int main ()
+{
+  foo x;
+
+  if (x.bar () != 16)
+    return 1;
+  if (x.bar() != 117)
+    return 1;
+  return 0;
+}