aboutsummaryrefslogtreecommitdiff
path: root/gcc/symtab.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-06-11 07:51:23 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-06-11 05:51:23 +0000
commite257a17cb9cc4dc76a79680616420e75ba030b5f (patch)
tree1eaa587ddb6f0f91bbd446438e1bb46f9b1df815 /gcc/symtab.c
parent58170a6621f1677c692634d28c4f67a24da42b13 (diff)
downloadgcc-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.c107
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. */