public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] Fix problems with -fdebug-types-section and local types
@ 2012-08-08  1:21 Cary Coutant
  2012-08-08 18:30 ` Cary Coutant
  0 siblings, 1 reply; 5+ messages in thread
From: Cary Coutant @ 2012-08-08  1:21 UTC (permalink / raw)
  To: gcc-patches, jason

With --std=c++11, a template parameter can refer to a local type defined
within a function.  Because that local type doesn't qualify for its own
type unit, we copy it as an "unworthy" type into the type unit that refers
to it, but we copy too much, leading to a comdat type unit that contains a
DIE with subprogram definitions rather than declarations.  These DIEs may
have DW_AT_low_pc/high_pc or DW_AT_ranges attributes, and consequently can
refer to range list entries that don't get emitted because they're not
marked when the compile unit is scanned, eventually causing an undefined
symbol at link time.

In addition, while debugging this problem, I found that the
DW_AT_object_pointer attribute, when left in the skeletons that are left
behind in the compile unit, causes duplicate copies of the types to be
copied back into the compile unit.

This patch fixes these problems by removing the DW_AT_object_pointer
attribute from the skeleton left behind in the compile unit, and by
copying DW_TAG_subprogram DIEs as declarations when copying "unworthy"
types into a type unit.  In order to preserve information in the DIE
structure, I also added DW_AT_abstract_origin as an attribute that
should be copied when cloning a DIE as a declaration.

I also fixed the dwarf4-typedef.C test, which should be turning on
the -fdebug-types-section flag.

Bootstrapped and tested on x86. OK for trunk?

-cary


2012-08-07   Cary Coutant  <ccoutant@google.com>

gcc/
	* dwarf2out.c (clone_as_declaration): Copy DW_AT_abstract_origin
	attribute.
	(generate_skeleton_bottom_up): Remove DW_AT_object_pointer attribute
	from original DIE.
	(clone_tree_hash): Rename to ...
	(clone_tree_partial): ... this; change callers.  Copy
	DW_TAG_subprogram DIEs as declarations.

gcc/testsuite/
	* testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C: New test case.
	* testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C: Add
	-fdebug-types-section flag.


Index: gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C
===================================================================
--- gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C	(revision 0)
+++ gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C	(revision 0)
@@ -0,0 +1,55 @@
+// { dg-do compile }
+// { dg-options "--std=c++11 -dA -gdwarf-4 -fdebug-types-section -fno-merge-debug-strings" }
+
+// Check that -fdebug-types-sections does not copy a full referenced type
+// into a type unit.
+
+// Checks that at least one type unit is generated.
+//
+// { dg-final { scan-assembler "DIE \\(.*\\) DW_TAG_type_unit" } }
+//
+// Check that func is declared exactly twice in the debug info:
+// once in the type unit for struct D, and once in the compile unit.
+//
+// { dg-final { scan-assembler-times "\\.ascii \"func\\\\0\"\[^\n\]*DW_AT_name" 2 } }
+//
+// Check to make sure that no type unit contains a DIE with DW_AT_low_pc
+// or DW_AT_ranges.  These patterns assume that the compile unit is always
+// emitted after all type units.
+//
+// { dg-final { scan-assembler-not "\\.quad.*DW_AT_low_pc.*DIE \\(.*\\) DW_TAG_compile_unit" } }
+// { dg-final { scan-assembler-not "\\.quad.*DW_AT_ranges.*DIE \\(.*\\) DW_TAG_compile_unit" } }
+
+struct A {
+  A();
+  virtual ~A();
+  virtual void foo();
+ private:
+  int data;
+};
+
+struct B {
+  B();
+  virtual ~B();
+};
+
+extern B* table[];
+
+struct D {
+  template <typename T>
+  T* get(int i)
+  {
+    B*& cell = table[i];
+    if (cell == 0)
+      cell = new T();
+    return static_cast<T*>(cell);
+  }
+};
+
+void func(D* d)
+{
+  struct C : B {
+    A a;
+  };
+  d->get<C>(0)->a.foo();
+}
Index: gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C
===================================================================
--- gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C	(revision 190189)
+++ gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-gdwarf-4" } */
+/* { dg-options "-gdwarf-4 -fdebug-types-section" } */
 
 /* Regression test for an ICE in output_die when using -gdwarf-4.  */
 
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 190189)
+++ gcc/dwarf2out.c	(working copy)
@@ -6357,6 +6357,7 @@ clone_as_declaration (dw_die_ref die)
 
       switch (a->dw_attr)
         {
+        case DW_AT_abstract_origin:
         case DW_AT_artificial:
         case DW_AT_containing_type:
         case DW_AT_external:
@@ -6489,6 +6490,12 @@ generate_skeleton_bottom_up (skeleton_ch
         dw_die_ref clone = clone_die (c);
         move_all_children (c, clone);
 
+        /* If the original has a DW_AT_object_pointer attribute,
+           it would now point to a child DIE just moved to the
+           cloned tree, so we need to remove that attribute from
+           the original.  */
+        remove_AT (c, DW_AT_object_pointer);
+
         replace_child (c, clone, prev);
         generate_skeleton_ancestor_tree (parent);
         add_child_die (parent->new_die, c);
@@ -6716,28 +6723,36 @@ copy_ancestor_tree (dw_die_ref unit, dw_
   return copy;
 }
 
-/* Like clone_tree, but additionally enter all the children into
-   the hash table decl_table.  */
+/* Like clone_tree, but copy DW_TAG_subprogram DIEs as declarations.
+   Enter all the cloned children into the hash table decl_table.  */
 
 static dw_die_ref
-clone_tree_hash (dw_die_ref die, htab_t decl_table)
+clone_tree_partial (dw_die_ref die, htab_t decl_table)
 {
   dw_die_ref c;
-  dw_die_ref clone = clone_die (die);
+  dw_die_ref clone;
   struct decl_table_entry *entry;
-  void **slot = htab_find_slot_with_hash (decl_table, die,
-					  htab_hash_pointer (die), INSERT);
+  void **slot;
+
+  if (die->die_tag == DW_TAG_subprogram)
+    clone = clone_as_declaration (die);
+  else
+    clone = clone_die (die);
+
+  slot = htab_find_slot_with_hash (decl_table, die,
+				   htab_hash_pointer (die), INSERT);
   /* Assert that DIE isn't in the hash table yet.  If it would be there
      before, the ancestors would be necessarily there as well, therefore
-     clone_tree_hash wouldn't be called.  */
+     clone_tree_partial wouldn't be called.  */
   gcc_assert (*slot == HTAB_EMPTY_ENTRY);
   entry = XCNEW (struct decl_table_entry);
   entry->orig = die;
   entry->copy = clone;
   *slot = entry;
 
-  FOR_EACH_CHILD (die, c,
-		  add_child_die (clone, clone_tree_hash (c, decl_table)));
+  if (die->die_tag != DW_TAG_subprogram)
+    FOR_EACH_CHILD (die, c,
+		    add_child_die (clone, clone_tree_partial (c, decl_table)));
 
   return clone;
 }
@@ -6790,7 +6805,8 @@ copy_decls_walk (dw_die_ref unit, dw_die
 
 	      FOR_EACH_CHILD (targ, c,
 			      add_child_die (copy,
-					     clone_tree_hash (c, decl_table)));
+					     clone_tree_partial (c,
+								 decl_table)));
 
               /* Make sure the cloned tree is marked as part of the
                  type unit.  */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Fix problems with -fdebug-types-section and local types
  2012-08-08  1:21 [patch] Fix problems with -fdebug-types-section and local types Cary Coutant
@ 2012-08-08 18:30 ` Cary Coutant
  2012-08-13 20:13   ` Cary Coutant
  0 siblings, 1 reply; 5+ messages in thread
From: Cary Coutant @ 2012-08-08 18:30 UTC (permalink / raw)
  To: gcc-patches, jason

> Index: gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C
> ===================================================================
> --- gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C   (revision 0)
> +++ gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C   (revision 0)
> @@ -0,0 +1,55 @@
> +// { dg-do compile }
> +// { dg-options "--std=c++11 -dA -gdwarf-4 -fdebug-types-section -fno-merge-debug-strings" }
> +
> +// Check that -fdebug-types-sections does not copy a full referenced type
> +// into a type unit.
> +
> +// Checks that at least one type unit is generated.
> +//
> +// { dg-final { scan-assembler "DIE \\(.*\\) DW_TAG_type_unit" } }
> +//
> +// Check that func is declared exactly twice in the debug info:
> +// once in the type unit for struct D, and once in the compile unit.
> +//
> +// { dg-final { scan-assembler-times "\\.ascii \"func\\\\0\"\[^\n\]*DW_AT_name" 2 } }
> +//
> +// Check to make sure that no type unit contains a DIE with DW_AT_low_pc
> +// or DW_AT_ranges.  These patterns assume that the compile unit is always
> +// emitted after all type units.
> +//
> +// { dg-final { scan-assembler-not "\\.quad.*DW_AT_low_pc.*DIE \\(.*\\) DW_TAG_compile_unit" } }
> +// { dg-final { scan-assembler-not "\\.quad.*DW_AT_ranges.*DIE \\(.*\\) DW_TAG_compile_unit" } }

I found a minor problem with the regexps above -- I was using ".*" in
a few places where I should have been using "\[^\n\]*". Fixed as
follows:

+// { dg-final { scan-assembler "DIE \\(\[^\n\]*\\) DW_TAG_type_unit" } }

+// { dg-final { scan-assembler-times "\\.ascii
\"func\\\\0\"\[^\n\]*DW_AT_name" 2 } }

+// { dg-final { scan-assembler-not "\\.quad\[^\n\]*DW_AT_low_pc.*DIE
\\(\[^\n\]*\\) DW_TAG_compile_unit" } }
+// { dg-final { scan-assembler-not "\\.quad\[^\n\]*DW_AT_ranges.*DIE
\\(\[^\n\]*\\) DW_TAG_compile_unit" } }

(Sorry, these will probably get split into two lines by gmail, but
they're each a single line in the actual patch.)

-cary

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Fix problems with -fdebug-types-section and local types
  2012-08-08 18:30 ` Cary Coutant
@ 2012-08-13 20:13   ` Cary Coutant
  2012-08-20 20:31     ` Cary Coutant
  0 siblings, 1 reply; 5+ messages in thread
From: Cary Coutant @ 2012-08-13 20:13 UTC (permalink / raw)
  To: gcc-patches, jason

> 2012-08-07   Cary Coutant  <ccoutant@google.com>
>
> gcc/
>         * dwarf2out.c (clone_as_declaration): Copy DW_AT_abstract_origin
>         attribute.
>         (generate_skeleton_bottom_up): Remove DW_AT_object_pointer attribute
>         from original DIE.
>         (clone_tree_hash): Rename to ...
>         (clone_tree_partial): ... this; change callers.  Copy
>         DW_TAG_subprogram DIEs as declarations.
>
> gcc/testsuite/
>         * testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C: New test case.
>         * testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C: Add
>         -fdebug-types-section flag.

Ping?

-cary

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Fix problems with -fdebug-types-section and local types
  2012-08-13 20:13   ` Cary Coutant
@ 2012-08-20 20:31     ` Cary Coutant
  2012-08-29 18:55       ` Cary Coutant
  0 siblings, 1 reply; 5+ messages in thread
From: Cary Coutant @ 2012-08-20 20:31 UTC (permalink / raw)
  To: gcc-patches, jason

Ping.

http://gcc.gnu.org/ml/gcc-patches/2012-08/msg00398.html

-cary

On Mon, Aug 13, 2012 at 1:13 PM, Cary Coutant <ccoutant@google.com> wrote:
>> 2012-08-07   Cary Coutant  <ccoutant@google.com>
>>
>> gcc/
>>         * dwarf2out.c (clone_as_declaration): Copy DW_AT_abstract_origin
>>         attribute.
>>         (generate_skeleton_bottom_up): Remove DW_AT_object_pointer attribute
>>         from original DIE.
>>         (clone_tree_hash): Rename to ...
>>         (clone_tree_partial): ... this; change callers.  Copy
>>         DW_TAG_subprogram DIEs as declarations.
>>
>> gcc/testsuite/
>>         * testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C: New test case.
>>         * testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C: Add
>>         -fdebug-types-section flag.
>
> Ping?
>
> -cary

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Fix problems with -fdebug-types-section and local types
  2012-08-20 20:31     ` Cary Coutant
@ 2012-08-29 18:55       ` Cary Coutant
  0 siblings, 0 replies; 5+ messages in thread
From: Cary Coutant @ 2012-08-29 18:55 UTC (permalink / raw)
  To: gcc-patches, jason

> Ping.
>
> http://gcc.gnu.org/ml/gcc-patches/2012-08/msg00398.html

Because much of this patch was superceded by this recent patch:

   http://gcc.gnu.org/ml/gcc-patches/2012-08/msg01968.html

I'll combine the two and submit a new patch.

-cary

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-08-29 18:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-08  1:21 [patch] Fix problems with -fdebug-types-section and local types Cary Coutant
2012-08-08 18:30 ` Cary Coutant
2012-08-13 20:13   ` Cary Coutant
2012-08-20 20:31     ` Cary Coutant
2012-08-29 18:55       ` Cary Coutant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).