re PR tree-optimization/46469 (ICE: verify_cgraph_node failed: inline clone is needed...
authorJan Hubicka <jh@suse.cz>
Sat, 8 Jan 2011 16:33:57 +0000 (17:33 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 8 Jan 2011 16:33:57 +0000 (16:33 +0000)
PR tree-optmization/46469
* ipa.c (function_and_variable_visibility): Clear needed flags on
nodes with external decls; handle weakrefs merging correctly.

* g++.dg/torture/pr46469.C: New testcase.

From-SVN: r168598

gcc/ChangeLog
gcc/ipa.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr46469.C [new file with mode: 0644]

index c05048f76f4e9110b1b4ce389b965ae4ad715b26..aec3bbe491895f361ec91cd30282957782123f0f 100644 (file)
@@ -1,3 +1,9 @@
+2011-01-07  Jan Hubicka  <jh@suse.cz>
+
+       PR tree-optmization/46469
+       * ipa.c (function_and_variable_visibility): Clear needed flags on
+       nodes with external decls; handle weakrefs merging correctly.
+
 2011-01-07  Joseph Myers  <joseph@codesourcery.com>
 
        * opts.c (finish_options): Set opts->x_flag_opts_finished to true,
index cf0a5b3ed7db1ba1d40df42fff04f42b696ca77e..fa39f92925d2f14edc99fa385bc3fd2f3721a84c 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -844,16 +844,32 @@ function_and_variable_visibility (bool whole_program)
                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
                IDENTIFIER_POINTER (p->target));
                
-      if ((node = cgraph_node_for_asm (p->target)) != NULL)
+      if ((node = cgraph_node_for_asm (p->target)) != NULL
+         && !DECL_EXTERNAL (node->decl))
         {
+         /* Weakrefs alias symbols from other compilation unit.  In the case
+            the destination of weakref became available because of LTO, we must
+            mark it as needed.  */
+         if (in_lto_p
+             && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
+             && !node->needed)
+           cgraph_mark_needed_node (node);
          gcc_assert (node->needed);
          pointer_set_insert (aliased_nodes, node);
          if (dump_file)
            fprintf (dump_file, "  node %s/%i",
                     cgraph_node_name (node), node->uid);
         }
-      else if ((vnode = varpool_node_for_asm (p->target)) != NULL)
+      else if ((vnode = varpool_node_for_asm (p->target)) != NULL
+              && !DECL_EXTERNAL (vnode->decl))
         {
+         /* Weakrefs alias symbols from other compilation unit.  In the case
+            the destination of weakref became available because of LTO, we must
+            mark it as needed.  */
+         if (in_lto_p
+             && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
+             && !vnode->needed)
+           varpool_mark_needed_node (vnode);
          gcc_assert (vnode->needed);
          pointer_set_insert (aliased_vnodes, vnode);
          if (dump_file)
@@ -867,6 +883,8 @@ function_and_variable_visibility (bool whole_program)
   for (node = cgraph_nodes; node; node = node->next)
     {
       int flags = flags_from_decl_or_type (node->decl);
+
+      /* Optimize away PURE and CONST constructors and destructors.  */
       if (optimize
          && (flags & (ECF_CONST | ECF_PURE))
          && !(flags & ECF_LOOPING_CONST_OR_PURE))
@@ -875,6 +893,13 @@ function_and_variable_visibility (bool whole_program)
          DECL_STATIC_DESTRUCTOR (node->decl) = 0;
        }
 
+      /* Frontends and alias code marks nodes as needed before parsing is finished.
+        We may end up marking as node external nodes where this flag is meaningless
+        strip it.  */
+      if (node->needed
+         && (DECL_EXTERNAL (node->decl) || !node->analyzed))
+       node->needed = 0;
+
       /* C++ FE on lack of COMDAT support create local COMDAT functions
         (that ought to be shared but can not due to object format
         limitations).  It is neccesary to keep the flag to make rest of C++ FE
index 968564ead4ac5d9c820f13242c78c278b079f837..09ae61f3e710e605eacf04890bcc4f610abd0ae2 100644 (file)
@@ -1,3 +1,8 @@
+2011-01-08  Jan Hubicka  <jh@suse.cz>
+
+       PR tree-optmization/46469
+       * g++.dg/torture/pr46469.C: New testcase.
+
 2011-01-08  Iain Sandoe  <iains@gcc.gnu.org>
 
        * objc-obj-c++-shared/next-mapping.h: Move code and definitions for
diff --git a/gcc/testsuite/g++.dg/torture/pr46469.C b/gcc/testsuite/g++.dg/torture/pr46469.C
new file mode 100644 (file)
index 0000000..8212ea4
--- /dev/null
@@ -0,0 +1,13 @@
+extern "C"  __inline __attribute__ ((__gnu_inline__)) int pthread_equal ()
+  {
+  }
+
+static
+  __typeof
+  (pthread_equal)
+  __gthrw_pthread_equal __attribute__ ((__weakref__ ("pthread_equal")));
+
+int identifierByPthreadHandle ()
+{
+  pthread_equal ();
+}