aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2011-01-08 17:33:57 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2011-01-08 16:33:57 +0000
commit8cb114b9a9de2adee05ef1d91b30986f8e27d329 (patch)
tree4928e7afc4c094955e19fca3ef23c8bed38d3360
parentd5dc93f4464d315c1ee2f5d72377381529b88208 (diff)
downloadgcc-8cb114b9a9de2adee05ef1d91b30986f8e27d329.zip
gcc-8cb114b9a9de2adee05ef1d91b30986f8e27d329.tar.gz
gcc-8cb114b9a9de2adee05ef1d91b30986f8e27d329.tar.bz2
re PR tree-optimization/46469 (ICE: verify_cgraph_node failed: inline clone is needed at -O)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ipa.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr46469.C13
4 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c05048f..aec3bbe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/ipa.c b/gcc/ipa.c
index cf0a5b3..fa39f92 100644
--- 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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 968564e..09ae61f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..8212ea4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr46469.C
@@ -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 ();
+}