diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-01-26 21:44:49 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-01-26 21:44:49 +0000 |
commit | fbb24ccf676d9d2029bbc293f0634a2ab8c39df7 (patch) | |
tree | 1f43f54af8acabd8d284a7ddcd24f5708f9f1963 /gcc/dwarf2out.c | |
parent | 425bd7b124fe9800471bb581c0b5fc2f01885363 (diff) | |
download | gcc-fbb24ccf676d9d2029bbc293f0634a2ab8c39df7.tar.gz |
PR debug/78835
* dwarf2out.c (prune_unused_types): Mark all functions with DIEs
which have direct callers with -fvar-tracking-assignments enabled
in the current TU.
(resolve_addr): Avoid adding skeleton DIEs for DW_AT_call_origin
inside of type units.
* g++.dg/debug/dwarf2/pr78835.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@244954 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 46565705506..f69c58850f3 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -27793,6 +27793,25 @@ prune_unused_types (void) for (i = 0; base_types.iterate (i, &base_type); i++) prune_unused_types_mark (base_type, 1); + /* For -fvar-tracking-assignments, also set the mark on nodes that could be + referenced by DW_TAG_call_site DW_AT_call_origin (i.e. direct call + callees). */ + cgraph_node *cnode; + FOR_EACH_FUNCTION (cnode) + if (cnode->referred_to_p (false)) + { + dw_die_ref die = lookup_decl_die (cnode->decl); + if (die == NULL || die->die_mark) + continue; + for (cgraph_edge *e = cnode->callers; e; e = e->next_caller) + if (e->caller != cnode + && opt_for_fn (e->caller->decl, flag_var_tracking_assignments)) + { + prune_unused_types_mark (die, 1); + break; + } + } + if (debug_str_hash) debug_str_hash->empty (); if (skeleton_debug_str_hash) @@ -28694,16 +28713,27 @@ resolve_addr (dw_die_ref die) && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE && (cdie = lookup_context_die (DECL_CONTEXT (tdecl)))) { - /* Creating a full DIE for tdecl is overly expensive and - at this point even wrong when in the LTO phase - as it can end up generating new type DIEs we didn't - output and thus optimize_external_refs will crash. */ - tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE); - add_AT_flag (tdie, DW_AT_external, 1); - add_AT_flag (tdie, DW_AT_declaration, 1); - add_linkage_attr (tdie, tdecl); - add_name_and_src_coords_attributes (tdie, tdecl); - equate_decl_number_to_die (tdecl, tdie); + dw_die_ref pdie = cdie; + /* Make sure we don't add these DIEs into type units. + We could emit skeleton DIEs for context (namespaces, + outer structs/classes) and a skeleton DIE for the + innermost context with DW_AT_signature pointing to the + type unit. See PR78835. */ + while (pdie && pdie->die_tag != DW_TAG_type_unit) + pdie = pdie->die_parent; + if (pdie == NULL) + { + /* Creating a full DIE for tdecl is overly expensive and + at this point even wrong when in the LTO phase + as it can end up generating new type DIEs we didn't + output and thus optimize_external_refs will crash. */ + tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE); + add_AT_flag (tdie, DW_AT_external, 1); + add_AT_flag (tdie, DW_AT_declaration, 1); + add_linkage_attr (tdie, tdecl); + add_name_and_src_coords_attributes (tdie, tdecl); + equate_decl_number_to_die (tdecl, tdie); + } } if (tdie) { |