+2014-05-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/47202
+ * cgraph.h (symtab_node::get_comdat_group_id): New.
+ * cgraphunit.c (analyze_functions): Call it.
+ * symtab.c (dump_symtab_node): Likewise.
+ * tree.c (decl_comdat_group_id): New.
+ * tree.h: Declare it.
+ * lto-streamer-out.c (write_symbol): Use it.
+ * trans-mem.c (ipa_tm_create_version_alias): Likewise.
+
2014-05-28 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR bootstrap/PR61146
return comdat_group_;
}
+ tree get_comdat_group_id ()
+ {
+ if (comdat_group_ && TREE_CODE (comdat_group_) != IDENTIFIER_NODE)
+ comdat_group_ = DECL_ASSEMBLER_NAME (comdat_group_);
+ return comdat_group_;
+ }
+
/* Set comdat group. */
void set_comdat_group (tree group)
{
node != first_analyzed
&& node != first_analyzed_var; node = node->next)
{
+ /* Convert COMDAT group designators to IDENTIFIER_NODEs. */
+ node->get_comdat_group_id ();
if (decide_is_symbol_needed (node))
{
enqueue_node (node);
2014-05-28 Jason Merrill <jason@redhat.com>
+ PR c++/47202
+ * decl.c (cxx_comdat_group): Return a decl.
+ * optimize.c (cdtor_comdat_group): Get its DECL_ASSEMBLER_NAME.
+
* pt.c (tsubst) [ARRAY_TYPE]: Check for array of array of unknown
bound.
return DECL_MAIN_P (decl);
}
-/* Return the COMDAT group into which DECL should be placed. */
+/* Return the decl used to identify the COMDAT group into which DECL should
+ be placed. */
tree
cxx_comdat_group (tree decl)
{
- tree name;
-
/* Virtual tables, construction virtual tables, and virtual table
tables all go in a single COMDAT group, named after the primary
virtual table. */
if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
- name = DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (DECL_CONTEXT (decl)));
+ decl = CLASSTYPE_VTABLES (DECL_CONTEXT (decl));
/* For all other DECLs, the COMDAT group is the mangled name of the
declaration itself. */
else
else
break;
}
- name = DECL_ASSEMBLER_NAME (decl);
}
- return name;
+ return decl;
}
/* Returns the return type for FN as written by the user, which may include
if (vague_linkage_p (decl))
DECL_WEAK (alias) = 1;
if (TREE_CODE (decl) == FUNCTION_DECL)
- cgraph_same_body_alias (cgraph_get_create_node (decl), alias, decl);
+ {
+ /* Don't create an alias to an unreferenced function. */
+ if (struct cgraph_node *n = cgraph_get_node (decl))
+ cgraph_same_body_alias (n, alias, decl);
+ }
else
varpool_extra_name_alias (alias, decl);
#endif
complete_name = cxx_comdat_group (complete);
if (base_name == NULL)
base_name = cxx_comdat_group (base);
+ complete_name = DECL_ASSEMBLER_NAME (complete_name);
+ base_name = DECL_ASSEMBLER_NAME (base_name);
gcc_assert (IDENTIFIER_LENGTH (complete_name)
== IDENTIFIER_LENGTH (base_name));
grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
size = 0;
if (DECL_ONE_ONLY (t))
- comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t));
+ comdat = IDENTIFIER_POINTER (decl_comdat_group_id (t));
else
comdat = "";
fprintf (f, " comdat");
if (node->get_comdat_group ())
fprintf (f, " comdat_group:%s",
- IDENTIFIER_POINTER (node->get_comdat_group ()));
+ IDENTIFIER_POINTER (node->get_comdat_group_id ()));
if (DECL_ONE_ONLY (node->decl))
fprintf (f, " one_only");
if (DECL_SECTION_NAME (node->decl))
node->analyzed = true;
ipa_record_reference (node, target, IPA_REF_ALIAS, NULL);
- /* Alias targets become reudndant after alias is resolved into an reference.
+ /* 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. */
node->alias_target = NULL;
/* Perform the same remapping to the comdat group. */
if (DECL_ONE_ONLY (new_decl))
- varpool_get_node (new_decl)->set_comdat_group (tm_mangle (DECL_COMDAT_GROUP (old_decl)));
+ varpool_get_node (new_decl)->set_comdat_group (tm_mangle (decl_comdat_group_id (old_decl)));
new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
new_node->tm_clone = true;
return DECL_WITH_VIS_CHECK (decl)->decl_with_vis.assembler_name;
}
-/* Return comdat group of DECL. */
+/* When the target supports COMDAT groups, this indicates which group the
+ DECL is associated with. This can be either an IDENTIFIER_NODE or a
+ decl, in which case its DECL_ASSEMBLER_NAME identifies the group. */
tree
decl_comdat_group (tree node)
{
return snode->get_comdat_group ();
}
+/* Likewise, but make sure it's been reduced to an IDENTIFIER_NODE. */
+tree
+decl_comdat_group_id (tree node)
+{
+ struct symtab_node *snode = symtab_get_node (node);
+ if (!snode)
+ return NULL;
+ return snode->get_comdat_group_id ();
+}
+
/* Compute the number of bytes occupied by a tree with code CODE.
This function cannot be used for nodes that have variable sizes,
including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR. */
extern tree decl_assembler_name (tree);
extern tree decl_comdat_group (tree);
+extern tree decl_comdat_group_id (tree);
/* Compute the number of bytes occupied by 'node'. This routine only
looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */