From c128931791b3abe8af1e6019dc79511228c2f919 Mon Sep 17 00:00:00 2001 From: ccoutant Date: Wed, 12 Jun 2013 18:49:17 +0000 Subject: [PATCH] Backport upstream patches to fix ICEs when using -fdebug-types-section. gcc: 2012-08-09 Cary Coutant Backport of pending upstream patch. * 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. 2012-08-22 Cary Coutant * dwarf2out.c (should_move_die_to_comdat): A type definition can contain a subprogram definition, but don't move it to a comdat unit. 2012-08-29 Cary Coutant * dwarf2out.c (clone_tree_partial): Remove. (copy_decls_walk): Don't copy children of a declaration into a type unit. 2012-08-31 Cary Coutant * dwarf2out.c (clone_tree_partial): Restore. (copy_decls_walk): Call clone_tree_partial to copy children of non-declaration DIEs. gcc/testsuite: 2012-08-09 Cary Coutant Backport of pending upstream patch. * g++.dg/debug/dwarf2/dwarf4-nested.C: New test case. * g++.dg/debug/dwarf2/dwarf4-typedef.C: Add -fdebug-types-section flag. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/google@200036 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc-4_8/gcc/dwarf2out.c | 54 ++++++++++++++------- .../testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C | 55 ++++++++++++++++++++++ .../testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C | 2 +- 3 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C diff --git a/gcc-4_8/gcc/dwarf2out.c b/gcc-4_8/gcc/dwarf2out.c index 35635d53c6e..f317b2a8714 100644 --- a/gcc-4_8/gcc/dwarf2out.c +++ b/gcc-4_8/gcc/dwarf2out.c @@ -6762,14 +6762,13 @@ should_move_die_to_comdat (dw_die_ref die) case DW_TAG_structure_type: case DW_TAG_enumeration_type: case DW_TAG_union_type: - /* Don't move declarations, inlined instances, or types nested in a - subprogram. */ + /* Don't move declarations, inlined instances, types nested in a + subprogram, or types that contain subprogram definitions. */ if (is_declaration_die (die) || get_AT (die, DW_AT_abstract_origin) - || is_nested_in_subprogram (die)) + || is_nested_in_subprogram (die) + || contains_subprogram_definition (die)) return 0; - /* A type definition should never contain a subprogram definition. */ - gcc_assert (!contains_subprogram_definition (die)); return 1; case DW_TAG_array_type: case DW_TAG_interface_type: @@ -6858,6 +6857,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: @@ -6990,6 +6990,12 @@ generate_skeleton_bottom_up (skeleton_chain_node *parent) 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); @@ -7217,28 +7223,36 @@ copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, htab_t decl_table) 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; } @@ -7289,9 +7303,15 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table) entry->copy = copy; *slot = entry; - FOR_EACH_CHILD (targ, c, - add_child_die (copy, - clone_tree_hash (c, decl_table))); + /* If TARG is not a declaration DIE, we need to copy its + children. */ + if (!is_declaration_die (targ)) + { + FOR_EACH_CHILD ( + targ, c, + add_child_die (copy, + clone_tree_partial (c, decl_table))); + } /* Make sure the cloned tree is marked as part of the type unit. */ diff --git a/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C b/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C new file mode 100644 index 00000000000..9d26419d496 --- /dev/null +++ b/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C @@ -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 \\(\[^\n\]*\\) 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\[^\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" } } + +struct A { + A(); + virtual ~A(); + virtual void foo(); + private: + int data; +}; + +struct B { + B(); + virtual ~B(); +}; + +extern B* table[]; + +struct D { + template + T* get(int i) + { + B*& cell = table[i]; + if (cell == 0) + cell = new T(); + return static_cast(cell); + } +}; + +void func(D* d) +{ + struct C : B { + A a; + }; + d->get(0)->a.foo(); +} diff --git a/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C b/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C index c5520fa72b0..89a6bb44e10 100644 --- a/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C +++ b/gcc-4_8/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C @@ -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. */ -- 2.11.4.GIT