diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-06-11 07:51:23 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-06-11 05:51:23 +0000 |
commit | e257a17cb9cc4dc76a79680616420e75ba030b5f (patch) | |
tree | 1eaa587ddb6f0f91bbd446438e1bb46f9b1df815 /gcc/symtab.c | |
parent | 58170a6621f1677c692634d28c4f67a24da42b13 (diff) | |
download | gcc-e257a17cb9cc4dc76a79680616420e75ba030b5f.zip gcc-e257a17cb9cc4dc76a79680616420e75ba030b5f.tar.gz gcc-e257a17cb9cc4dc76a79680616420e75ba030b5f.tar.bz2 |
varasm.c (set_implicit_section): New function.
* varasm.c (set_implicit_section): New function.
(resolve_unique_section): Use it to set implicit section
for aliases, too.
(get_named_text_section): Use symtab_get_node (decl)->implicit_section
(default_function_section): Likewise.
(decl_binds_to_current_def_p): Constify argument.
* varasm.h (decl_binds_to_current_def_p): Update prototype.
* asan.c (asan_protect_global): Use symtab_get_node (decl)->implicit_section.
* symtab.c (dump_symtab_base): Dump implicit sections.
(verify_symtab_base): Verify sanity of sectoins and comdats.
(symtab_resolve_alias): Alias share the section of its target.
(set_section_1): New function.
(symtab_node::set_section): Move here, recurse to aliases.
(verify_symtab): Check for duplicated symtab lists.
* tree-core.h (implicit_section_name_p): Remove.
* tree-vect-data-refs.c: Include varasm.h.
(vect_can_force_dr_alignment_p): Fix conditional on when
decl bints to current definition; use
symtab_get_node (decl)->implicit_section.
* cgraph.c (cgraph_make_node_local_1): Fix section set.
* cgraph.h (struct symtab_node): Add implicit_section.
(set_section): Rename to ...
(set_section_for_node): ... this one.
(set_section): Declare.
* tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): Remove.
* lto-cgraph.c (lto_output_node, lto_output_varpool_node,
input_overwrite_node, input_varpool_node): Stream implicit_section.
* ipa.c (symtab_remove_unreachable_nodes): Do not check symtab before
removal; it will fail in LTO.
* vtable-class-hierarchy.c: Use symtab_get_node (var_decl)->implicit_section.
* optimize.c (cdtor_comdat_group): Fix handling of aliases.
(maybe_clone_body): Move symbol across comdat groups.
* method.c (use_thunk): Copy implicit section flag.
* go/go-gcc.cc (Gcc_backend::global_variable_set_init): Use
symtab_get_node(var_decl)->implicit_section.
* lto.c (read_cgraph_and_symbols): Remove unreachable symbols.
(do_whole_program_analysis): Use verify_symtab.
From-SVN: r211434
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r-- | gcc/symtab.c | 107 |
1 files changed, 105 insertions, 2 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c index 8265b4e..d7977f1 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -565,7 +565,9 @@ dump_symtab_base (FILE *f, symtab_node *node) fprintf (f, " one_only"); if (node->get_section ()) fprintf (f, " section:%s", - TREE_STRING_POINTER (node->get_section ())); + node->get_section ()); + if (node->implicit_section) + fprintf (f," (implicit_section)"); if (DECL_VISIBILITY_SPECIFIED (node->decl)) fprintf (f, " visibility_specified"); if (DECL_VISIBILITY (node->decl)) @@ -791,6 +793,7 @@ verify_symtab_base (symtab_node *node) { struct ipa_ref_list *refs = &node->ref_list; struct ipa_ref *ref; + for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i) { if (!symtab_in_same_comdat_p (ref->referring, node)) @@ -803,6 +806,38 @@ verify_symtab_base (symtab_node *node) } } } + if (node->implicit_section && !node->get_section ()) + { + error ("implicit_section flag is set but section isn't"); + error_found = true; + } + if (node->get_section () && node->get_comdat_group () + && !node->implicit_section) + { + error ("Both section and comdat group is set"); + error_found = true; + } + /* TODO: Add string table for sections, so we do not keep holding duplicated + strings. */ + if (node->alias && node->definition + && node->get_section () != symtab_alias_target (node)->get_section () + && (!node->get_section() + || !symtab_alias_target (node)->get_section () + || strcmp (node->get_section(), + symtab_alias_target (node)->get_section ()))) + { + error ("Alias and target's section differs"); + dump_symtab_node (stderr, symtab_alias_target (node)); + error_found = true; + } + if (node->alias && node->definition + && node->get_comdat_group () != symtab_alias_target (node)->get_comdat_group ()) + { + error ("Alias and target's comdat groups differs"); + dump_symtab_node (stderr, symtab_alias_target (node)); + error_found = true; + } + return error_found; } @@ -832,8 +867,30 @@ DEBUG_FUNCTION void verify_symtab (void) { symtab_node *node; + pointer_map<symtab_node *> comdat_head_map; + FOR_EACH_SYMBOL (node) - verify_symtab_node (node); + { + verify_symtab_node (node); + if (node->get_comdat_group ()) + { + symtab_node **entry, *s; + bool existed; + + entry = comdat_head_map.insert (node->get_comdat_group (), &existed); + if (!existed) + *entry = node; + else + for (s = (*entry)->same_comdat_group; s != NULL && s != node; s = s->same_comdat_group) + if (!s || s == *entry) + { + error ("Two symbols with same comdat_group are not linked by the same_comdat_group list."); + dump_symtab_node (stderr, *entry); + dump_symtab_node (stderr, s); + internal_error ("verify_symtab failed"); + } + } + } } /* Return true when RESOLUTION indicate that linker will use @@ -1024,6 +1081,33 @@ fixup_same_cpp_alias_visibility (symtab_node *node, symtab_node *target) node->externally_visible = target->externally_visible; } +/* Worker for set_section. */ + +static bool +set_section_1 (struct symtab_node *n, void *s) +{ + n->set_section_for_node ((tree)s); + return false; +} + +/* Set section of symbol and its aliases. */ + +void +symtab_node::set_section (tree section) +{ + gcc_assert (!this->alias); + symtab_for_node_and_aliases (this, set_section_1, section, true); +} + +/* Worker for symtab_resolve_alias. */ + +static bool +set_implicit_section (struct symtab_node *n, void *data ATTRIBUTE_UNUSED) +{ + n->implicit_section = true; + return false; +} + /* Add reference recording that NODE is alias of TARGET. The function can fail in the case of aliasing cycles; in this case it returns false. */ @@ -1058,6 +1142,25 @@ symtab_resolve_alias (symtab_node *node, symtab_node *target) node->analyzed = true; ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); + /* Add alias into the comdat group of its target unless it is already there. */ + if (node->same_comdat_group) + symtab_remove_from_same_comdat_group (node); + node->set_comdat_group (NULL); + if (target->get_comdat_group ()) + symtab_add_to_same_comdat_group (node, target); + + if ((node->get_section () != target->get_section () + || target->get_comdat_group ()) + && node->get_section () && !node->implicit_section) + { + error ("section of alias %q+D must match section of its target", + node->decl); + } + symtab_for_node_and_aliases (node, set_section_1, target->get_section_name (), true); + if (target->implicit_section) + symtab_for_node_and_aliases (node, + set_implicit_section, NULL, true); + /* Alias targets become redundant after alias is resolved into an reference. We do not want to keep it around or we would have to mind updating them when renaming symbols. */ |