aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-11-09 10:36:24 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-11-09 10:36:24 +0000
commit6496e42f8734797b1a5613585c47e51398419547 (patch)
tree35a95043c534b6a727a3d427c998055634f68924 /gcc
parentd8ef0f496a05addb5f8dd32ce60859fc7ea00bf2 (diff)
downloadgcc-6496e42f8734797b1a5613585c47e51398419547.zip
gcc-6496e42f8734797b1a5613585c47e51398419547.tar.gz
gcc-6496e42f8734797b1a5613585c47e51398419547.tar.bz2
re PR middle-end/46221 (huge number of c++ testsuite failures, libstdc++.so alias missing)
2010-11-09 Richard Guenther <rguenther@suse.de> PR middle-end/46221 * varasm.c (compute_visible_aliases): New function. (remove_unreachable_alias_pairs): Aliases make a target available even though we reclaimed the cgraph node. (finish_aliases_1): Likewise. * Makefile.in (varasm.o): Add pointer-set.h dependency. * gcc.target/i386/alias-1.c: New testcase. From-SVN: r166479
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/alias-1.c9
-rw-r--r--gcc/varasm.c60
5 files changed, 83 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9b543d5..5c73a47 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2010-11-09 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/46221
+ * varasm.c (compute_visible_aliases): New function.
+ (remove_unreachable_alias_pairs): Aliases make a target available
+ even though we reclaimed the cgraph node.
+ (finish_aliases_1): Likewise.
+ * Makefile.in (varasm.o): Add pointer-set.h dependency.
+
2010-11-09 Nick Clifton <nickc@redhat.com>
* config/mn10300/mn10300-modes.def: New file.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 459dbee..cc58d7f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2884,7 +2884,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
output.h $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \
$(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h \
- tree-iterator.h
+ tree-iterator.h pointer-set.h
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \
$(TREE_H) $(CFGLAYOUT_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \
$(OPTABS_H) $(LIBFUNCS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 38bf312..c4fa079 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-09 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/46221
+ * gcc.target/i386/alias-1.c: New testcase.
+
2010-11-08 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-sassert.C: New.
diff --git a/gcc/testsuite/gcc.target/i386/alias-1.c b/gcc/testsuite/gcc.target/i386/alias-1.c
new file mode 100644
index 0000000..adbe2f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/alias-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+int yum;
+void dessert (void) { ++yum; }
+extern void jelly (void) __attribute__ ((alias ("dessert"), weak));
+extern void wobbly (void) __attribute__ ((alias ("jelly"), weak));
+
+/* { dg-final { scan-assembler "wobbly" } } */
+/* { dg-final { scan-assembler "jelly" } } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index fe60bb2..0c80c93 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfglayout.h"
#include "basic-block.h"
#include "tree-iterator.h"
+#include "pointer-set.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -5415,18 +5416,58 @@ do_assemble_alias (tree decl, tree target)
}
+/* Compute the set of indentifier nodes that is generated by aliases
+ whose targets are reachable. */
+
+static struct pointer_set_t *
+compute_visible_aliases (void)
+{
+ struct pointer_set_t *visible;
+ unsigned i;
+ alias_pair *p;
+ bool changed;
+
+ /* We have to compute the set of visible nodes including aliases
+ themselves. */
+ visible = pointer_set_create ();
+ do
+ {
+ changed = false;
+ for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i)
+ {
+ struct cgraph_node *fnode = NULL;
+ struct varpool_node *vnode = NULL;
+ fnode = cgraph_node_for_asm (p->target);
+ vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL;
+ if ((fnode
+ || vnode
+ || pointer_set_contains (visible, p->target))
+ && !pointer_set_insert (visible, DECL_ASSEMBLER_NAME (p->decl)))
+ changed = true;
+ }
+ }
+ while (changed);
+
+ return visible;
+}
+
/* Remove the alias pairing for functions that are no longer in the call
graph. */
void
remove_unreachable_alias_pairs (void)
{
+ struct pointer_set_t *visible;
unsigned i;
alias_pair *p;
if (alias_pairs == NULL)
return;
+ /* We have to compute the set of visible nodes including aliases
+ themselves. */
+ visible = compute_visible_aliases ();
+
for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); )
{
if (!DECL_EXTERNAL (p->decl))
@@ -5435,7 +5476,9 @@ remove_unreachable_alias_pairs (void)
struct varpool_node *vnode = NULL;
fnode = cgraph_node_for_asm (p->target);
vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL;
- if (fnode == NULL && vnode == NULL)
+ if (!fnode
+ && !vnode
+ && !pointer_set_contains (visible, p->target))
{
VEC_unordered_remove (alias_pair, alias_pairs, i);
continue;
@@ -5444,6 +5487,8 @@ remove_unreachable_alias_pairs (void)
i++;
}
+
+ pointer_set_destroy (visible);
}
@@ -5453,9 +5498,17 @@ remove_unreachable_alias_pairs (void)
void
finish_aliases_1 (void)
{
+ struct pointer_set_t *visible;
unsigned i;
alias_pair *p;
+ if (alias_pairs == NULL)
+ return;
+
+ /* We have to compute the set of visible nodes including aliases
+ themselves. */
+ visible = compute_visible_aliases ();
+
FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
{
tree target_decl;
@@ -5463,6 +5516,9 @@ finish_aliases_1 (void)
target_decl = find_decl_and_mark_needed (p->decl, p->target);
if (target_decl == NULL)
{
+ if (pointer_set_contains (visible, p->target))
+ continue;
+
if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF)
&& ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
{
@@ -5485,6 +5541,8 @@ finish_aliases_1 (void)
p->emitted_diags |= ALIAS_DIAG_TO_EXTERN;
}
}
+
+ pointer_set_destroy (visible);
}
/* Second pass of completing pending aliases. Emit the actual assembly.