cgraph.c (cgraph_add_to_same_comdat_group): New.
authorJason Merrill <jason@redhat.com>
Sat, 9 Jul 2011 03:33:44 +0000 (23:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 9 Jul 2011 03:33:44 +0000 (23:33 -0400)
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.

From-SVN: r176071

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cp/ChangeLog
gcc/cp/method.c
gcc/cp/optimize.c
gcc/cp/semantics.c
gcc/ipa.c

index 34ebb0aa9abe0db21838f677f03eb12bfd8fcb6d..c2d866da6a2fa284fdaa6cc75f79770e5121e59a 100644 (file)
@@ -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
index 86e72072eabfbddeef974997a37fb8a01282e9b3..09aad60c4d2d5fe6fc85a80ecd1975e3e2cbeaf1 100644 (file)
@@ -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
index 91339230a16d52f806307d3e329436ae5527a8b2..5d6ff7caf61f5ce2bf0c37f91d66190731c80e82 100644 (file)
@@ -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);
index 41157a1de837f6654a33da4038b67d398cdb5c4c..3f776b097ad84bcfadd615693049e855f0ec8695 100644 (file)
@@ -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.
index d41a4dd4238d11fb5cf4ca6e37fde112911d8df6..3d272a33f6192b94966cb76b8389a4edfd98e3a9 100644 (file)
@@ -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,
index b9e3551b40c3e094217d1dba97b452a1a3a12a3d..6a06988039837a5abb1805bf406f1f25ed6bf49d 100644 (file)
@@ -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;
 }
index 5c53a18511c4c037b812e6df386eb158fb9c644f..84b0dd8559fc1822072e022ff97fec6cbe692e5f 100644 (file)
@@ -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);
index 5b09250d661cd9a0eaff960cfc7084bdeb1fde6b..9d54811e5c9e8eef6c2b11fde45a0eca31ef82f2 100644 (file)
--- 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;