summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-07-09 03:33:44 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-07-09 03:33:44 +0000
commitdabebf7ecc90b59b0603d2428cf465fe1f0d642b (patch)
tree91cf7e9a3eeaae34dd4f07d9086f498096305f0d /gcc
parent63aa3890e81a12aaac274e04e4967bb4abfb7d7a (diff)
downloadgcc-dabebf7ecc90b59b0603d2428cf465fe1f0d642b.tar.gz
gcc/
* cgraph.c (cgraph_add_to_same_comdat_group): New. * cgraph.h: Declare it. * ipa.c (function_and_variable_visibility): Make sure thunks have the right visibility. gcc/cp/ * method.c (use_thunk): Use cgraph_add_to_same_comdat_group. * optimize.c (maybe_clone_body): Likewise. * semantics.c (maybe_add_lambda_conv_op): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176071 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cgraph.c25
-rw-r--r--gcc/cgraph.h1
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/method.c13
-rw-r--r--gcc/cp/optimize.c41
-rw-r--r--gcc/cp/semantics.c10
-rw-r--r--gcc/ipa.c29
8 files changed, 68 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 34ebb0aa9ab..c2d866da6a2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2011-07-08 Jason Merrill <jason@redhat.com>
+
+ * cgraph.c (cgraph_add_to_same_comdat_group): New.
+ * cgraph.h: Declare it.
+ * ipa.c (function_and_variable_visibility): Make sure thunks
+ have the right visibility.
+
2011-07-08 Richard Henderson <rth@redhat.com>
PR bootstrap/49680
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 86e72072eab..09aad60c4d2 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1630,6 +1630,31 @@ cgraph_remove_node (struct cgraph_node *node)
free_nodes = node;
}
+/* Add NEW_ to the same comdat group that OLD is in. */
+
+void
+cgraph_add_to_same_comdat_group (struct cgraph_node *new_,
+ struct cgraph_node *old)
+{
+ gcc_assert (DECL_ONE_ONLY (old->decl));
+ gcc_assert (!new_->same_comdat_group);
+ gcc_assert (new_ != old);
+
+ DECL_COMDAT_GROUP (new_->decl) = DECL_COMDAT_GROUP (old->decl);
+ new_->same_comdat_group = old;
+ if (!old->same_comdat_group)
+ old->same_comdat_group = new_;
+ else
+ {
+ struct cgraph_node *n;
+ for (n = old->same_comdat_group;
+ n->same_comdat_group != old;
+ n = n->same_comdat_group)
+ ;
+ n->same_comdat_group = new_;
+ }
+}
+
/* Remove the node from cgraph. */
void
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 91339230a16..5d6ff7caf61 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -469,6 +469,7 @@ void debug_cgraph_node (struct cgraph_node *);
void cgraph_insert_node_to_hashtable (struct cgraph_node *node);
void cgraph_remove_edge (struct cgraph_edge *);
void cgraph_remove_node (struct cgraph_node *);
+void cgraph_add_to_same_comdat_group (struct cgraph_node *, struct cgraph_node *);
void cgraph_remove_node_and_inline_clones (struct cgraph_node *);
void cgraph_release_function_body (struct cgraph_node *);
void cgraph_node_remove_callees (struct cgraph_node *node);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 41157a1de83..3f776b097ad 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2011-07-08 Jason Merrill <jason@redhat.com>
+ * method.c (use_thunk): Use cgraph_add_to_same_comdat_group.
+ * optimize.c (maybe_clone_body): Likewise.
+ * semantics.c (maybe_add_lambda_conv_op): Likewise.
+
PR c++/45603
* decl.c (expand_static_init): Don't get confused by user
declaration of __cxa_guard_acquire.
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d41a4dd4238..3d272a33f61 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -283,7 +283,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
tree virtual_offset;
HOST_WIDE_INT fixed_offset, virtual_value;
bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
- struct cgraph_node *funcn;
+ struct cgraph_node *funcn, *thunk_node;
/* We should have called finish_thunk to give it a name. */
gcc_assert (DECL_NAME (thunk_fndecl));
@@ -344,8 +344,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
= DECL_VISIBILITY_SPECIFIED (function);
DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function);
- if (DECL_ONE_ONLY (function) || DECL_WEAK (function))
- make_decl_one_only (thunk_fndecl, cxx_comdat_group (thunk_fndecl));
+ DECL_WEAK (thunk_fndecl) = DECL_WEAK (function);
if (flag_syntax_only)
{
@@ -386,9 +385,11 @@ use_thunk (tree thunk_fndecl, bool emit_p)
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
funcn = cgraph_get_node (function);
gcc_checking_assert (funcn);
- cgraph_add_thunk (funcn, thunk_fndecl, function,
- this_adjusting, fixed_offset, virtual_value,
- virtual_offset, alias);
+ thunk_node = cgraph_add_thunk (funcn, thunk_fndecl, function,
+ this_adjusting, fixed_offset, virtual_value,
+ virtual_offset, alias);
+ if (DECL_ONE_ONLY (function))
+ cgraph_add_to_same_comdat_group (thunk_node, funcn);
if (!this_adjusting
|| !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index b9e3551b40c..6a069880398 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -309,12 +309,12 @@ maybe_clone_body (tree fn)
&& (!DECL_ONE_ONLY (fns[0])
|| (HAVE_COMDAT_GROUP
&& DECL_WEAK (fns[0])))
- && (flag_syntax_only
- /* Set linkage flags appropriately before
- cgraph_create_function_alias looks at them. */
- || (expand_or_defer_fn_1 (clone)
- && cgraph_same_body_alias (cgraph_get_node (fns[0]),
- clone, fns[0]))))
+ && !flag_syntax_only
+ /* Set linkage flags appropriately before
+ cgraph_create_function_alias looks at them. */
+ && expand_or_defer_fn_1 (clone)
+ && cgraph_same_body_alias (cgraph_get_node (fns[0]),
+ clone, fns[0]))
{
alias = true;
if (DECL_ONE_ONLY (fns[0]))
@@ -324,13 +324,22 @@ maybe_clone_body (tree fn)
*[CD][12]*. */
comdat_group = cdtor_comdat_group (fns[1], fns[0]);
DECL_COMDAT_GROUP (fns[0]) = comdat_group;
+ cgraph_add_to_same_comdat_group (cgraph_get_node (clone),
+ cgraph_get_node (fns[0]));
}
}
/* Build the delete destructor by calling complete destructor
and delete function. */
if (idx == 2)
- build_delete_destructor_body (clone, fns[1]);
+ {
+ build_delete_destructor_body (clone, fns[1]);
+ /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
+ virtual, it goes into the same comdat group as well. */
+ if (comdat_group)
+ cgraph_add_to_same_comdat_group (cgraph_get_create_node (clone),
+ cgraph_get_node (fns[0]));
+ }
else if (alias)
/* No need to populate body. */ ;
else
@@ -419,24 +428,6 @@ maybe_clone_body (tree fn)
}
pop_from_top_level ();
- if (comdat_group)
- {
- DECL_COMDAT_GROUP (fns[1]) = comdat_group;
- if (fns[2])
- {
- struct cgraph_node *base_dtor_node, *deleting_dtor_node;
- /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
- virtual, it goes into the same comdat group as well. */
- DECL_COMDAT_GROUP (fns[2]) = comdat_group;
- base_dtor_node = cgraph_get_node (fns[0]);
- deleting_dtor_node = cgraph_get_node (fns[2]);
- gcc_assert (base_dtor_node->same_comdat_group == NULL);
- gcc_assert (deleting_dtor_node->same_comdat_group == NULL);
- base_dtor_node->same_comdat_group = deleting_dtor_node;
- deleting_dtor_node->same_comdat_group = base_dtor_node;
- }
- }
-
/* We don't need to process the original function any further. */
return 1;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5c53a18511c..84b0dd8559f 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8880,14 +8880,8 @@ maybe_add_lambda_conv_op (tree type)
if (DECL_ONE_ONLY (statfn))
{
/* Put the thunk in the same comdat group as the call op. */
- struct cgraph_node *callop_node, *thunk_node;
- DECL_COMDAT_GROUP (statfn) = cxx_comdat_group (callop);
- callop_node = cgraph_get_create_node (callop);
- thunk_node = cgraph_get_create_node (statfn);
- gcc_assert (callop_node->same_comdat_group == NULL);
- gcc_assert (thunk_node->same_comdat_group == NULL);
- callop_node->same_comdat_group = thunk_node;
- thunk_node->same_comdat_group = callop_node;
+ cgraph_add_to_same_comdat_group (cgraph_get_create_node (statfn),
+ cgraph_get_create_node (callop));
}
body = begin_function_body ();
compound_stmt = begin_compound_stmt (0);
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 5b09250d661..9d54811e5c9 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -865,31 +865,14 @@ function_and_variable_visibility (bool whole_program)
decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
/* Thunks have the same visibility as function they are attached to.
- For some reason C++ frontend don't seem to care. I.e. in
- g++.dg/torture/pr41257-2.C the thunk is not comdat while function
- it is attached to is.
-
- We also need to arrange the thunk into the same comdat group as
- the function it reffers to. */
+ Make sure the C++ front end set this up properly. */
if (DECL_ONE_ONLY (decl_node->decl))
{
- DECL_COMDAT (node->decl) = DECL_COMDAT (decl_node->decl);
- DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (decl_node->decl);
- if (DECL_ONE_ONLY (decl_node->decl) && !node->same_comdat_group)
- {
- node->same_comdat_group = decl_node;
- if (!decl_node->same_comdat_group)
- decl_node->same_comdat_group = node;
- else
- {
- struct cgraph_node *n;
- for (n = decl_node->same_comdat_group;
- n->same_comdat_group != decl_node;
- n = n->same_comdat_group)
- ;
- n->same_comdat_group = node;
- }
- }
+ gcc_checking_assert (DECL_COMDAT (node->decl)
+ == DECL_COMDAT (decl_node->decl));
+ gcc_checking_assert (DECL_COMDAT_GROUP (node->decl)
+ == DECL_COMDAT_GROUP (decl_node->decl));
+ gcc_checking_assert (node->same_comdat_group);
}
if (DECL_EXTERNAL (decl_node->decl))
DECL_EXTERNAL (node->decl) = 1;