diff options
author | Richard Guenther <rguenther@suse.de> | 2010-11-09 10:36:24 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-11-09 10:36:24 +0000 |
commit | 6496e42f8734797b1a5613585c47e51398419547 (patch) | |
tree | 35a95043c534b6a727a3d427c998055634f68924 /gcc | |
parent | d8ef0f496a05addb5f8dd32ce60859fc7ea00bf2 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/alias-1.c | 9 | ||||
-rw-r--r-- | gcc/varasm.c | 60 |
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. |