Commit d67ff7b7 by Jason Merrill Committed by Jason Merrill

re PR c++/47202 (Endless recursion during mangling)

	PR c++/47202
gcc/cp/
	* decl.c (cxx_comdat_group): Return a decl.
	* optimize.c (cdtor_comdat_group): Get its DECL_ASSEMBLER_NAME.
gcc/
	* 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.

From-SVN: r211026
parent a41acf5f
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> 2014-05-28 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR bootstrap/PR61146 PR bootstrap/PR61146
......
...@@ -147,6 +147,13 @@ public: ...@@ -147,6 +147,13 @@ public:
return comdat_group_; 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. */ /* Set comdat group. */
void set_comdat_group (tree group) void set_comdat_group (tree group)
{ {
......
...@@ -974,6 +974,8 @@ analyze_functions (void) ...@@ -974,6 +974,8 @@ analyze_functions (void)
node != first_analyzed node != first_analyzed
&& node != first_analyzed_var; node = node->next) && 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)) if (decide_is_symbol_needed (node))
{ {
enqueue_node (node); enqueue_node (node);
......
2014-05-28 Jason Merrill <jason@redhat.com> 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 * pt.c (tsubst) [ARRAY_TYPE]: Check for array of array of unknown
bound. bound.
......
...@@ -14484,18 +14484,17 @@ cp_missing_noreturn_ok_p (tree decl) ...@@ -14484,18 +14484,17 @@ cp_missing_noreturn_ok_p (tree decl)
return DECL_MAIN_P (decl); 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 tree
cxx_comdat_group (tree decl) cxx_comdat_group (tree decl)
{ {
tree name;
/* Virtual tables, construction virtual tables, and virtual table /* Virtual tables, construction virtual tables, and virtual table
tables all go in a single COMDAT group, named after the primary tables all go in a single COMDAT group, named after the primary
virtual table. */ virtual table. */
if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl)) 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 /* For all other DECLs, the COMDAT group is the mangled name of the
declaration itself. */ declaration itself. */
else else
...@@ -14513,10 +14512,9 @@ cxx_comdat_group (tree decl) ...@@ -14513,10 +14512,9 @@ cxx_comdat_group (tree decl)
else else
break; break;
} }
name = DECL_ASSEMBLER_NAME (decl);
} }
return name; return decl;
} }
/* Returns the return type for FN as written by the user, which may include /* Returns the return type for FN as written by the user, which may include
......
...@@ -3520,7 +3520,11 @@ mangle_decl (const tree decl) ...@@ -3520,7 +3520,11 @@ mangle_decl (const tree decl)
if (vague_linkage_p (decl)) if (vague_linkage_p (decl))
DECL_WEAK (alias) = 1; DECL_WEAK (alias) = 1;
if (TREE_CODE (decl) == FUNCTION_DECL) 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 else
varpool_extra_name_alias (alias, decl); varpool_extra_name_alias (alias, decl);
#endif #endif
......
...@@ -170,6 +170,8 @@ cdtor_comdat_group (tree complete, tree base) ...@@ -170,6 +170,8 @@ cdtor_comdat_group (tree complete, tree base)
complete_name = cxx_comdat_group (complete); complete_name = cxx_comdat_group (complete);
if (base_name == NULL) if (base_name == NULL)
base_name = cxx_comdat_group (base); 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) gcc_assert (IDENTIFIER_LENGTH (complete_name)
== IDENTIFIER_LENGTH (base_name)); == IDENTIFIER_LENGTH (base_name));
grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1); grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
......
...@@ -2329,7 +2329,7 @@ write_symbol (struct streamer_tree_cache_d *cache, ...@@ -2329,7 +2329,7 @@ write_symbol (struct streamer_tree_cache_d *cache,
size = 0; size = 0;
if (DECL_ONE_ONLY (t)) if (DECL_ONE_ONLY (t))
comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t)); comdat = IDENTIFIER_POINTER (decl_comdat_group_id (t));
else else
comdat = ""; comdat = "";
......
...@@ -560,7 +560,7 @@ dump_symtab_base (FILE *f, symtab_node *node) ...@@ -560,7 +560,7 @@ dump_symtab_base (FILE *f, symtab_node *node)
fprintf (f, " comdat"); fprintf (f, " comdat");
if (node->get_comdat_group ()) if (node->get_comdat_group ())
fprintf (f, " comdat_group:%s", fprintf (f, " comdat_group:%s",
IDENTIFIER_POINTER (node->get_comdat_group ())); IDENTIFIER_POINTER (node->get_comdat_group_id ()));
if (DECL_ONE_ONLY (node->decl)) if (DECL_ONE_ONLY (node->decl))
fprintf (f, " one_only"); fprintf (f, " one_only");
if (DECL_SECTION_NAME (node->decl)) if (DECL_SECTION_NAME (node->decl))
...@@ -1062,7 +1062,7 @@ symtab_resolve_alias (symtab_node *node, symtab_node *target) ...@@ -1062,7 +1062,7 @@ symtab_resolve_alias (symtab_node *node, symtab_node *target)
node->analyzed = true; node->analyzed = true;
ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); 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 We do not want to keep it around or we would have to mind updating them
when renaming symbols. */ when renaming symbols. */
node->alias_target = NULL; node->alias_target = NULL;
......
...@@ -4852,7 +4852,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data) ...@@ -4852,7 +4852,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
/* Perform the same remapping to the comdat group. */ /* Perform the same remapping to the comdat group. */
if (DECL_ONE_ONLY (new_decl)) 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 = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
new_node->tm_clone = true; new_node->tm_clone = true;
......
...@@ -603,7 +603,9 @@ decl_assembler_name (tree decl) ...@@ -603,7 +603,9 @@ decl_assembler_name (tree decl)
return DECL_WITH_VIS_CHECK (decl)->decl_with_vis.assembler_name; 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 tree
decl_comdat_group (tree node) decl_comdat_group (tree node)
{ {
...@@ -613,6 +615,16 @@ decl_comdat_group (tree node) ...@@ -613,6 +615,16 @@ decl_comdat_group (tree node)
return snode->get_comdat_group (); 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. /* Compute the number of bytes occupied by a tree with code CODE.
This function cannot be used for nodes that have variable sizes, This function cannot be used for nodes that have variable sizes,
including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR. */ including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR. */
......
...@@ -3432,6 +3432,7 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, ...@@ -3432,6 +3432,7 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
extern tree decl_assembler_name (tree); extern tree decl_assembler_name (tree);
extern tree decl_comdat_group (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 /* 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. */ looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment